re PR target/46091 (missed optimization: x86 bt/btc/bts instructions)
authorUros Bizjak <ubizjak@gmail.com>
Mon, 14 Aug 2017 16:42:15 +0000 (18:42 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 14 Aug 2017 16:42:15 +0000 (18:42 +0200)
PR target/46091
* config/i386/i386.md (*anddi_1_btr): New insn_and_split pattern.
(*iordi_1_bts): Ditto.
(*xordi_1_btc): Ditto.

testsuite/ChangeLog:

PR target/46091
* gcc.target/i386/pr46091-1.c: New test.
* gcc.target/i386/pr46091-2.c: Ditto.
* gcc.target/i386/pr46091-3.c: Ditto.

From-SVN: r251095

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr46091-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr46091-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr46091-3.c [new file with mode: 0644]

index 8bc4e2228b10930f3b5e354d5f12a0da82ff0337..4c147b06d11dc88bf36f4a53b62512e2905bbaab 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-14  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/46091
+       * config/i386/i386.md (*anddi_1_btr): New insn_and_split pattern.
+       (*iordi_1_bts): Ditto.
+       (*xordi_1_btc): Ditto.
+
 2017-08-14  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        PR target/79845
index 8cf6d21c82a77a38a22c5c5ac4da1b7ddd009069..059a51832deccfefc825b9b2d6476557593c97b7 100644 (file)
        (const_string "*")))
    (set_attr "mode" "SI,DI,DI,SI")])
 
+(define_insn_and_split "*anddi_1_btr"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (and:DI
+        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 2 "const_int_operand" "n")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_64BIT && TARGET_USE_BT
+   && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (zero_extract:DI (match_dup 0)
+                                   (const_int 1)
+                                   (match_dup 3))
+                  (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])]
+  "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "znver1_decode" "double")
+   (set_attr "mode" "DI")])
+
 ;; Turn *anddi_1 into *andsi_1_zext if possible.
 (define_split
   [(set (match_operand:DI 0 "register_operand")
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
+(define_insn_and_split "*iordi_1_bts"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (ior:DI
+        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 2 "const_int_operand" "n")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_64BIT && TARGET_USE_BT
+   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (zero_extract:DI (match_dup 0)
+                                   (const_int 1)
+                                   (match_dup 3))
+                  (const_int 1))
+             (clobber (reg:CC FLAGS_REG))])]
+  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "znver1_decode" "double")
+   (set_attr "mode" "DI")])
+
+(define_insn_and_split "*xordi_1_btc"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (xor:DI
+        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 2 "const_int_operand" "n")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_64BIT && TARGET_USE_BT
+   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (zero_extract:DI (match_dup 0)
+                                   (const_int 1)
+                                   (match_dup 3))
+                  (not:DI (zero_extract:DI (match_dup 0)
+                                           (const_int 1)
+                                           (match_dup 3))))
+             (clobber (reg:CC FLAGS_REG))])]
+  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "znver1_decode" "double")
+   (set_attr "mode" "DI")])
+
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 (define_insn "*<code>si_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
index bfe2f7826ed3a41ebfb0948522c51718c61600d2..18dac95e7e8b54f70def9b16d1074ce39bdf058d 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-14  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/46091
+       * gcc.target/i386/pr46091-1.c: New test.
+       * gcc.target/i386/pr46091-2.c: Ditto.
+       * gcc.target/i386/pr46091-3.c: Ditto.
+
 2017-08-14  Wilco Dijkstra  <wdijkstr@arm.com>
 
        PR target/81643
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-1.c b/gcc/testsuite/gcc.target/i386/pr46091-1.c
new file mode 100644 (file)
index 0000000..adca01f
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+  return a & ~(1ull << 55);
+}
+
+/* { dg-final { scan-assembler "btr" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-2.c b/gcc/testsuite/gcc.target/i386/pr46091-2.c
new file mode 100644 (file)
index 0000000..1743753
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+  return a | (1ull << 55);
+}
+
+/* { dg-final { scan-assembler "bts" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-3.c b/gcc/testsuite/gcc.target/i386/pr46091-3.c
new file mode 100644 (file)
index 0000000..c8091e9
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+  return a ^ (1ull << 55);
+}
+
+/* { dg-final { scan-assembler "btc" } } */