re PR target/85683 (GCC 8 stopped using RMW (Read Modify Write) instructions on x86...
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 May 2018 16:17:34 +0000 (18:17 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 May 2018 16:17:34 +0000 (18:17 +0200)
PR target/85683
* config/i386/i386.md: Add peepholes for mem {+,-,&,|,^}= x; mem != 0
after cmpelim optimization.

* gcc.target/i386/pr49095.c: Add -masm=att to dg-options.  Add
scan-assembler-times checking that except for [fh]*xor other functions
don't use any load instructions.

From-SVN: r260045

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr49095.c

index 654cacbc25ad0997c3364572a40f485f68bf70a6..17208954394c1de901c8af4fc1c913296fa29046 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/85683
+       * config/i386/i386.md: Add peepholes for mem {+,-,&,|,^}= x; mem != 0
+       after cmpelim optimization.
+
 2018-05-08  Olga Makhotina  <olga.makhotina@intel.com>
 
        * config.gcc: Support "goldmont".
index ad28961a8263611cef9e661588bbe1df2cffdceb..97b1ca318006dc1baf3caa7ea719a8728dd3c84d 100644 (file)
                       const0_rtx);
 })
 
+;; Likewise for cmpelim optimized pattern.
+(define_peephole2
+  [(set (match_operand:SWI 0 "register_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (reg FLAGS_REG)
+                  (compare (match_operator:SWI 3 "plusminuslogic_operator"
+                             [(match_dup 0)
+                              (match_operand:SWI 2 "<nonmemory_operand>")])
+                           (const_int 0)))
+             (set (match_dup 0) (match_dup 3))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && ix86_match_ccmode (peep2_next_insn (1),
+                        (GET_CODE (operands[3]) == PLUS
+                         || GET_CODE (operands[3]) == MINUS)
+                        ? CCGOCmode : CCNOmode)"
+  [(parallel [(set (match_dup 4) (match_dup 6))
+             (set (match_dup 1) (match_dup 5))])]
+{
+  operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
+  operands[5]
+    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
+                     copy_rtx (operands[1]), operands[2]);
+  operands[6]
+    = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
+                      const0_rtx);
+})
+
 ;; Likewise for instances where we have a lea pattern.
 (define_peephole2
   [(set (match_operand:SWI 0 "register_operand")
                       const0_rtx);
 })
 
+;; Likewise for cmpelim optimized pattern.
+(define_peephole2
+  [(parallel [(set (reg FLAGS_REG)
+                  (compare (match_operator:SWI 2 "plusminuslogic_operator"
+                             [(match_operand:SWI 0 "register_operand")
+                              (match_operand:SWI 1 "memory_operand")])
+                           (const_int 0)))
+             (set (match_dup 0) (match_dup 2))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (2, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && ix86_match_ccmode (peep2_next_insn (0),
+                        (GET_CODE (operands[2]) == PLUS
+                         || GET_CODE (operands[2]) == MINUS)
+                        ? CCGOCmode : CCNOmode)"
+  [(parallel [(set (match_dup 3) (match_dup 5))
+             (set (match_dup 1) (match_dup 4))])]
+{
+  operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
+  operands[4]
+    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
+                     copy_rtx (operands[1]), operands[0]);
+  operands[5]
+    = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
+                      const0_rtx);
+})
+
 (define_peephole2
   [(set (match_operand:SWI12 0 "register_operand")
        (match_operand:SWI12 1 "memory_operand"))
index d601ed182ae095ae4ce0b1869c2087cdf1cce4c8..bd65daa518a08590fa990a3a333b4290d157b9bc 100644 (file)
@@ -1,3 +1,10 @@
+2018-05-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/85683
+       * gcc.target/i386/pr49095.c: Add -masm=att to dg-options.  Add
+       scan-assembler-times checking that except for [fh]*xor other functions
+       don't use any load instructions.
+
 2018-05-08  Olga Makhotina  <olga.makhotina@intel.com>
 
        * gcc.target/i386/builtin_target.c: Test goldmont.
index 73758f8c523479d512b1cb8ba8c78b957c0053fc..078071910638b076a749b847552e260d8c45ab04 100644 (file)
@@ -1,6 +1,6 @@
 /* PR rtl-optimization/49095 */
 /* { dg-do compile } */
-/* { dg-options "-Os -fno-shrink-wrap" } */
+/* { dg-options "-Os -fno-shrink-wrap -masm=att" } */
 /* { dg-additional-options "-mregparm=2" { target ia32 } } */
 
 void foo (void *);
@@ -71,3 +71,6 @@ G (int)
 G (long)
 
 /* { dg-final { scan-assembler-not "test\[lq\]" } } */
+/* The {f,h}{char,short,int,long}xor functions aren't optimized into
+   a RMW instruction, so need load, modify and store.  FIXME eventually.  */
+/* { dg-final { scan-assembler-times "\\), %" 8 } } */