[i386] : Correct RMW operation with LEA peephole (PR 89865)

Message ID CAFULd4YZKtUE=jKpD6s0rvS5=sgTGs=OU25mDp144yKznP89zQ@mail.gmail.com
State New
Headers show
Series
  • [i386] : Correct RMW operation with LEA peephole (PR 89865)
Related show

Commit Message

Uros Bizjak March 28, 2019, 7:40 p.m.
Attached patch corrects RMW operation with LEA peephole pattern. The
mode of the LEA is either SImode (for QImode, HImode or SImode
operation) or DImode.

2019-03-28  UroŇ° Bizjak  <ubizjak@gmail.com>

    PR target/89865
    * config/i386/i386.md (RMW operation with LEA peephole):
    Use LEAMODE mode attribute instead of SWI mode iterator for
    LEA pattern.

The patch triggers

FAIL: gcc.target/i386/pr49095.c scan-assembler-times \\\\), % 45

testsuite failure also for x86_64-linux-gnu. The adjusted number of
found patterns was wrong from the beginning and hid the uncovered
problem with LEA operation.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 269995)
+++ config/i386/i386.md	(working copy)
@@ -18684,14 +18684,16 @@ 
 (define_peephole2
   [(set (match_operand:SWI 0 "register_operand")
 	(match_operand:SWI 1 "memory_operand"))
-   (set (match_operand:SWI 3 "register_operand")
-	(plus:SWI (match_dup 0)
-		  (match_operand:SWI 2 "<nonmemory_operand>")))
-   (set (match_dup 1) (match_dup 3))
-   (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
+   (set (match_operand:<LEAMODE> 3 "register_operand")
+	(plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
+			(match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
+   (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
+   (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && REGNO (operands[4]) == REGNO (operands[0])
+   && REGNO (operands[5]) == REGNO (operands[3])
    && peep2_reg_dead_p (4, operands[3])
-   && (rtx_equal_p (operands[0], operands[3])
+   && ((REGNO (operands[0]) == REGNO (operands[3]))
        || peep2_reg_dead_p (2, operands[0]))
    && !reg_overlap_mentioned_p (operands[0], operands[1])
    && !reg_overlap_mentioned_p (operands[3], operands[1])
@@ -18700,17 +18702,17 @@ 
        || immediate_operand (operands[2], QImode)
        || any_QIreg_operand (operands[2], QImode))
    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
-  [(parallel [(set (match_dup 4) (match_dup 6))
-	      (set (match_dup 1) (match_dup 5))])]
+  [(parallel [(set (match_dup 6) (match_dup 8))
+	      (set (match_dup 1) (match_dup 7))])]
 {
-  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
-  operands[5]
+  operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
+  operands[7]
     = gen_rtx_PLUS (<MODE>mode,
 		    copy_rtx (operands[1]),
-		    operands[2]);
-  operands[6]
-    = gen_rtx_COMPARE (GET_MODE (operands[4]),
-		       copy_rtx (operands[5]),
+		    gen_lowpart (<MODE>mode, operands[2]));
+  operands[8]
+    = gen_rtx_COMPARE (GET_MODE (operands[6]),
+		       copy_rtx (operands[7]),
 		       const0_rtx);
 })