[committed] Fix m32r target bug exposed by Jakub's cselib.c changes

Message ID c6b8ece1810096169f22b7fc8363a806af60e2a6.camel@redhat.com
State New
Headers show
Series
  • [committed] Fix m32r target bug exposed by Jakub's cselib.c changes
Related show

Commit Message

Xionghu Luo via Gcc-patches April 3, 2020, 6:47 p.m.
va-arg-22.c started failing on the m32r target (-O1 only) after Jakub's recent
cselib changes.

The m32r port has this pattern:

(define_insn "cpymemsi_internal"
  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))   ;; destination
        (mem:BLK (match_operand:SI 1 "register_operand" "r")))  ;; source
   (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to
move
   (set (match_operand:SI 3 "register_operand" "=0")
        (plus:SI (minus (match_dup 2) (const_int 4))
                 (match_dup 0)))
   (set (match_operand:SI 4 "register_operand" "=1")
        (plus:SI (match_dup 1)
                 (match_dup 2)))
   (clobber (match_scratch:SI 5 "=&r"))  ;; temp1
   (clobber (match_scratch:SI 6 "=&r"))] ;; temp2

Note how it updates operand0/operand3 and operand1/operand4.  In simplest terms
it adds the # bytes copied to each operand.

When we output the assembly code for the pattern it has some smarts to avoid
doing half-word and byte loads to handle residuals -- instead it loads a full
word.  That's all fine and good, except the loads occur with post-increment
addressing so after we're done with the actual memory copies the source pointer
can actually point 1, 2 or 3 bytes beyond where it should.  To compound the
problem we then incorrectly manually adjust the operand to account for residuals
resulting in the source pointer pointing 2, 4 or 6 bytes past where it should.

In va-arg-22.c, when compiled with -O1, it turns out we want to use the adjusted
source pointer in a subsequent insn.  AFAICT, cselib didn't discover the
equivalence before, but does so now and with the bugs in the m32r port noted
above the pointer has the wrong value and all hell breaks loose.

This patch fixes the assembly code we generate for cpymemsi_internal.  Naturally
this fixes va-arg-22.c at -O1.  It doesn't fix any of the other long standing
failures though.

Committing to the trunk,

Jeff
commit b949f8e2acb49273b2f08ecaa3bc7128baaad850
Author: Jeff Law <law@redhat.com>
Date:   Fri Apr 3 12:46:13 2020 -0600

    Fix va-arg-22.c at -O1 on m32r.
    
            PR rtl-optimization/92264
            * config/m32r/m32r.c (m32r_output_block_move): Properly account for
            post-increment addressing of source operands as well as residuals
            when computing any adjustments to the input pointer.

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7083bbb9cce..e9dfa71ec0e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@ 
+2020-04-03  Jeff Law  <law@redhat.com>
+
+	PR rtl-optimization/92264
+	* config/m32r/m32r.c (m32r_output_block_move): Properly account for
+	post-increment addressing of source operands as well as residuals
+	when computing any adjustments to the input pointer.
+
 2020-04-03  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/94460
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 1c015609524..27fb495ed17 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -2676,7 +2676,7 @@  m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
 	     destination pointer.  */
 	  int dst_inc_amount = dst_offset + bytes - 4;
 	  /* The same for the source pointer.  */
-	  int src_inc_amount = bytes;
+	  int src_inc_amount = bytes - (got_extra ? 4 : 0);
 	  int last_shift;
 	  rtx my_operands[3];