re PR target/46091 (missed optimization: x86 bt/btc/bts instructions)
authorUros Bizjak <ubizjak@gmail.com>
Wed, 16 Aug 2017 15:25:34 +0000 (17:25 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 16 Aug 2017 15:25:34 +0000 (17:25 +0200)
PR target/46091
* config/i386/i386.md (*anddi_1_btr): Change predicates of
operand 0 and operand 1 to nomimmediate_operand. Add "m" constraint.
Add ix86_binary_operator_ok to insn constraint.
(*iordi_1_bts): Ditto.
(*xordi_1_btc): Ditto.
(*btsq): Change predicate of operand 0 to nonimmediate_operand.
Update corresponding peephole2 pattern.
(*btrq): Ditto.
(*btcq): Ditto.

testsuite/ChangeLog:

PR target/46091
* gcc.target/i386/pr46091-1.c: Update scan-assembler-times.
(testm): New test function.
* gcc.target/i386/pr46091-2.c: Ditto.
* gcc.target/i386/pr46091-3.c: Ditto.

From-SVN: r251124

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr46091-1.c
gcc/testsuite/gcc.target/i386/pr46091-2.c
gcc/testsuite/gcc.target/i386/pr46091-3.c

index eb3277224b021c6c6636d01faf4b95103109bbff..3eff5f5ff04ae52c42bcd8b961094331bb8c1c52 100644 (file)
@@ -1,3 +1,16 @@
+2017-08-16  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/46091
+       * config/i386/i386.md (*anddi_1_btr): Change predicates of
+       operand 0 and operand 1 to nomimmediate_operand. Add "m" constraint.
+       Add ix86_binary_operator_ok to insn constraint.
+       (*iordi_1_bts): Ditto.
+       (*xordi_1_btc): Ditto.
+       (*btsq): Change predicate of operand 0 to nonimmediate_operand.
+       Update corresponding peephole2 pattern.
+       (*btrq): Ditto.
+       (*btcq): Ditto.
+
 2017-08-16  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/81832
index 059a51832deccfefc825b9b2d6476557593c97b7..14688a863cf36acdee5adc260a0ffbbaae40ea5c 100644 (file)
    (set_attr "mode" "SI,DI,DI,SI")])
 
 (define_insn_and_split "*anddi_1_btr"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
        (and:DI
-        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 1 "nonimmediate_operand" "%0")
         (match_operand:DI 2 "const_int_operand" "n")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && TARGET_USE_BT
+   && ix86_binary_operator_ok (AND, DImode, operands)
    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
   "#"
   "&& reload_completed"
    (set_attr "mode" "<MODE>")])
 
 (define_insn_and_split "*iordi_1_bts"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
        (ior:DI
-        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 1 "nonimmediate_operand" "%0")
         (match_operand:DI 2 "const_int_operand" "n")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && TARGET_USE_BT
+   && ix86_binary_operator_ok (IOR, DImode, operands)
    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
   "#"
   "&& reload_completed"
    (set_attr "mode" "DI")])
 
 (define_insn_and_split "*xordi_1_btc"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
        (xor:DI
-        (match_operand:DI 1 "register_operand" "%0")
+        (match_operand:DI 1 "nonimmediate_operand" "%0")
         (match_operand:DI 2 "const_int_operand" "n")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && TARGET_USE_BT
+   && ix86_binary_operator_ok (XOR, DImode, operands)
    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
   "#"
   "&& reload_completed"
 ;; Bit set / bit test instructions
 
 ;; %%% bts, btr, btc, bt.
-;; In general these instructions are *slow* when applied to memory,
-;; since they enforce atomic operation.  When applied to registers,
-;; it depends on the cpu implementation.  They're never faster than
-;; the corresponding and/ior/xor operations, so with 32-bit there's
+;; In general these instructions are *slow* with variable operand
+;; when applied to memory.  When applied to registers, it depends
+;; on the cpu implementation.  They're never faster than the
+;; corresponding and/ior/xor operations, so with 32-bit there's
 ;; no point.  But in 64-bit, we can't hold the relevant immediates
 ;; within the instruction itself, so operating on bits in the high
 ;; 32-bits of a register becomes easier.
 ;; negdf respectively, so they can never be disabled entirely.
 
 (define_insn "*btsq"
-  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
+  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
                         (match_operand 1 "const_0_to_63_operand" "J"))
        (const_int 1))
    (set_attr "mode" "DI")])
 
 (define_insn "*btrq"
-  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
+  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
                         (match_operand 1 "const_0_to_63_operand" "J"))
        (const_int 0))
    (set_attr "mode" "DI")])
 
 (define_insn "*btcq"
-  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
+  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
                         (match_operand 1 "const_0_to_63_operand" "J"))
        (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
 (define_peephole2
   [(match_scratch:DI 2 "r")
    (parallel [(set (zero_extract:DI
-                    (match_operand:DI 0 "register_operand")
+                    (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
                     (match_operand 1 "const_0_to_63_operand"))
                   (const_int 1))
 (define_peephole2
   [(match_scratch:DI 2 "r")
    (parallel [(set (zero_extract:DI
-                    (match_operand:DI 0 "register_operand")
+                    (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
                     (match_operand 1 "const_0_to_63_operand"))
                   (const_int 0))
 (define_peephole2
   [(match_scratch:DI 2 "r")
    (parallel [(set (zero_extract:DI
-                    (match_operand:DI 0 "register_operand")
+                    (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
                     (match_operand 1 "const_0_to_63_operand"))
              (not:DI (zero_extract:DI
          (zero_extract:SWI48
            (match_operand:SWI48 0 "register_operand" "r")
            (const_int 1)
-           (match_operand:SI 1 "nonmemory_operand" "rN"))
+           (match_operand:SI 1 "nonmemory_operand" "r<S>"))
          (const_int 0)))]
   ""
 {
index 717e951a8ccbe609ae5bfa57c6feacee3033dcf6..2b4c63ab7123f2510f4a9c1312af81910e583ea8 100644 (file)
@@ -1,3 +1,11 @@
+2017-08-16  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/46091
+       * gcc.target/i386/pr46091-1.c: Update scan-assembler-times.
+       (testm): New test function.
+       * gcc.target/i386/pr46091-2.c: Ditto.
+       * gcc.target/i386/pr46091-3.c: Ditto.
+
 2017-08-16  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/81832
index adca01f294c19835c6a2076ce6c9d214e8999c10..74685af8184a6bc84222a6679dc157e000143400 100644 (file)
@@ -6,4 +6,11 @@ unsigned long long test (unsigned long long a)
   return a & ~(1ull << 55);
 }
 
-/* { dg-final { scan-assembler "btr" } } */
+extern unsigned long long m;
+
+void testm (void)
+{
+  m &= ~(1ull << 45);
+}
+
+/* { dg-final { scan-assembler-times "btr" 2 } } */
index 174375393cf572ec3464fa8e9b5340a7c0cc92bd..5b34045072587588c33ad929389b8161be68e624 100644 (file)
@@ -6,4 +6,11 @@ unsigned long long test (unsigned long long a)
   return a | (1ull << 55);
 }
 
-/* { dg-final { scan-assembler "bts" } } */
+extern unsigned long long m;
+
+void testm (void)
+{
+  m |= (1ull << 45);
+}
+
+/* { dg-final { scan-assembler-times "bts" 2 } } */
index c8091e9f41c02660c5b50eb9fb92ef725369e8ac..3c601a3c543a089200ab8b1738a6fc825dbd984f 100644 (file)
@@ -6,4 +6,11 @@ unsigned long long test (unsigned long long a)
   return a ^ (1ull << 55);
 }
 
-/* { dg-final { scan-assembler "btc" } } */
+extern unsigned long long m;
+
+void testm (void)
+{
+  m ^= (1ull << 45);
+}
+
+/* { dg-final { scan-assembler-times "btc" 2 } } */