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 <l...@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. 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 <l...@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 <ja...@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];