re PR rtl-optimization/89865 (FAIL: gcc.target/i386/pr49095.c scan-assembler-times...
authorJakub Jelinek <jakub@redhat.com>
Mon, 8 Apr 2019 12:36:58 +0000 (14:36 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 8 Apr 2019 12:36:58 +0000 (14:36 +0200)
PR rtl-optimization/89865
* config/i386/i386.md: Add peepholes for z = x; x ^= y; x != z.

* gcc.target/i386/pr49095.c: Don't expect any RMW sequences.

From-SVN: r270206

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

index 5ee20a9bbaa5d5a0e5190968005ed39c263be712..5339017821f294fb37b4420192f6eed0b671f767 100644 (file)
@@ -1,5 +1,8 @@
 2019-04-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/89865
+       * config/i386/i386.md: Add peepholes for z = x; x ^= y; x != z.
+
        PR rtl-optimization/89865
        * config/i386/i386.md
        (SWI12 peephole for mem {+,-,&,|,^}= x; mem != 0): Fix up operand
index b797e406a9202b670d958562f35ef0d6d291fb69..4188c1a96225c9eb7fcf03e932c6da0fef827aba 100644 (file)
                       const0_rtx);
 })
 
+;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
+;; into x = z; x ^= y; x != z
+(define_peephole2
+  [(set (match_operand:SWI 0 "register_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (set (match_operand:SWI 3 "register_operand") (match_dup 0))
+   (parallel [(set (match_operand:SWI 4 "register_operand")
+                  (xor:SWI (match_dup 4)
+                           (match_operand:SWI 2 "<nonmemory_operand>")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 1) (match_dup 4))
+   (set (reg:CCZ FLAGS_REG)
+       (compare:CCZ (match_operand:SWI 5 "register_operand")
+                    (match_operand:SWI 6 "<nonmemory_operand>")))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && (REGNO (operands[4]) == REGNO (operands[0])
+       || REGNO (operands[4]) == REGNO (operands[3]))
+   && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
+                            ? 3 : 0], operands[5])
+       ? rtx_equal_p (operands[2], operands[6])
+       : rtx_equal_p (operands[2], operands[5])
+        && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
+                                 ? 3 : 0], operands[6]))
+   && peep2_reg_dead_p (4, operands[4])
+   && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
+                                   ? 3 : 0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && !reg_overlap_mentioned_p (operands[3], operands[0])
+   && !reg_overlap_mentioned_p (operands[3], operands[1])
+   && !reg_overlap_mentioned_p (operands[3], operands[2])
+   && (<MODE>mode != QImode
+       || immediate_operand (operands[2], QImode)
+       || any_QIreg_operand (operands[2], QImode))"
+  [(parallel [(set (match_dup 7) (match_dup 9))
+             (set (match_dup 1) (match_dup 8))])]
+{
+  operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
+  operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
+                            operands[2]);
+  operands[9]
+    = gen_rtx_COMPARE (GET_MODE (operands[7]),
+                      copy_rtx (operands[8]),
+                      const0_rtx);
+})
+
+(define_peephole2
+  [(set (match_operand:SWI12 0 "register_operand")
+       (match_operand:SWI12 1 "memory_operand"))
+   (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
+   (parallel [(set (match_operand:SI 4 "register_operand")
+                  (xor:SI (match_dup 4)
+                          (match_operand:SI 2 "<nonmemory_operand>")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
+   (set (reg:CCZ FLAGS_REG)
+       (compare:CCZ (match_operand:SWI12 6 "register_operand")
+                    (match_operand:SWI12 7 "<nonmemory_operand>")))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && (REGNO (operands[5]) == REGNO (operands[0])
+       || REGNO (operands[5]) == REGNO (operands[3]))
+   && REGNO (operands[5]) == REGNO (operands[4])
+   && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
+                            ? 3 : 0], operands[6])
+       ? (REG_P (operands[2])
+         ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
+         : rtx_equal_p (operands[2], operands[7]))
+       : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
+                               ? 3 : 0], operands[7])
+         && REG_P (operands[2])
+         && REGNO (operands[2]) == REGNO (operands[6])))
+   && peep2_reg_dead_p (4, operands[5])
+   && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
+                                   ? 3 : 0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && !reg_overlap_mentioned_p (operands[3], operands[0])
+   && !reg_overlap_mentioned_p (operands[3], operands[1])
+   && !reg_overlap_mentioned_p (operands[3], operands[2])
+   && (<MODE>mode != QImode
+       || immediate_operand (operands[2], SImode)
+       || any_QIreg_operand (operands[2], SImode))"
+  [(parallel [(set (match_dup 8) (match_dup 10))
+             (set (match_dup 1) (match_dup 9))])]
+{
+  operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
+  operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
+                            gen_lowpart (<MODE>mode, operands[2]));
+  operands[10]
+    = gen_rtx_COMPARE (GET_MODE (operands[8]),
+                      copy_rtx (operands[9]),
+                      const0_rtx);
+})
+
 ;; Attempt to optimize away memory stores of values the memory already
 ;; has.  See PR79593.
 (define_peephole2
index 087c58b2e4f78858bcf5dab58d10bacb7e05db54..9b7b08d0e0e3ea7b11d4b472f6f5c788b54b5740 100644 (file)
@@ -1,5 +1,8 @@
 2019-04-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/89865
+       * gcc.target/i386/pr49095.c: Don't expect any RMW sequences.
+
        PR rtl-optimization/89865
        * gcc.target/i386/pr49095.c: Adjust number of expected RMW spots
        on ia32.
index 3ae14e3d4e0ef9345ba61818a7f26f3cd233c99b..f1295b3314016581f29e3ed60dd1d894c6be59fe 100644 (file)
@@ -71,7 +71,5 @@ 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 "\\(%eax\\), %" 8 { target { ia32 } } } } */
-/* { dg-final { scan-assembler-times "\\(%\[re\]di\\), %" 8 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "\\(%eax\\), %" { target { ia32 } } } } */
+/* { dg-final { scan-assembler-not "\\(%\[re\]di\\), %" { target { ! ia32 } } } } */