[backport from gcc-4.8/trunk r191875, dropped inapplicable sparc_fold_builtin changes ] From: Eric Botcazou Subject: [SPARC] Fix recent and older thinkos Date: Sun, 30 Sep 2012 19:51:32 +0200 List-Archive: This fixes a recent thinko introduced by the double-int rewrite and responsible for the following failures: FAIL: gcc.target/sparc/pdist-2.c scan-tree-dump optimized "return 475" FAIL: gcc.target/sparc/pdist-3.c execution test as well as an older one spotted by Bernd, whereby the compiler emits non- canonical RTL for the stack adjustments issued for the epilogue. The patch also contains a patchlet for reorg.c that performs a bit of manual CSE: XVECEXP (PATTERN (insn), 0, 0) --> delay_insn and which makes it more obvious why you can take JUMP_LABEL (delay_insn). Tested on SPARC/Linux, applied on the mainline. gcc/ 2012-09-30 Eric Botcazou * reorg.c (relax_delay_slots): Use delay_insn consistently. * config/sparc/sparc.c (gen_stack_pointer_dec): Delete. (sparc_expand_epilogue): Use gen_stack_pointer_inc and adjust. (sparc_flat_expand_epilogue): Likewise. (emit_and_preserve): Likewise. --- gcc-4.7.2/gcc/config/sparc/sparc.c.~1~ 2012-09-02 12:36:54.000000000 +0200 +++ gcc-4.7.2/gcc/config/sparc/sparc.c 2012-10-06 14:49:22.000000000 +0200 @@ -4915,18 +4915,6 @@ gen_stack_pointer_inc (rtx increment) increment)); } -/* Generate a decrement for the stack pointer. */ - -static rtx -gen_stack_pointer_dec (rtx decrement) -{ - return gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - gen_rtx_MINUS (Pmode, - stack_pointer_rtx, - decrement)); -} - /* Expand the function prologue. The prologue is responsible for reserving storage for the frame, saving the call-saved registers and loading the GOT register if needed. */ @@ -5197,17 +5185,17 @@ sparc_expand_epilogue (bool for_eh) else if (sparc_leaf_function_p) { if (size <= 4096) - emit_insn (gen_stack_pointer_dec (GEN_INT (-size))); + emit_insn (gen_stack_pointer_inc (GEN_INT (size))); else if (size <= 8192) { - emit_insn (gen_stack_pointer_dec (GEN_INT (-4096))); - emit_insn (gen_stack_pointer_dec (GEN_INT (4096 - size))); + emit_insn (gen_stack_pointer_inc (GEN_INT (4096))); + emit_insn (gen_stack_pointer_inc (GEN_INT (size - 4096))); } else { rtx reg = gen_rtx_REG (Pmode, 1); - emit_move_insn (reg, GEN_INT (-size)); - emit_insn (gen_stack_pointer_dec (reg)); + emit_move_insn (reg, GEN_INT (size)); + emit_insn (gen_stack_pointer_inc (reg)); } } } @@ -5257,17 +5245,17 @@ sparc_flat_expand_epilogue (bool for_eh) emit_insn (gen_blockage ()); if (size <= 4096) - emit_insn (gen_stack_pointer_dec (GEN_INT (-size))); + emit_insn (gen_stack_pointer_inc (GEN_INT (size))); else if (size <= 8192) { - emit_insn (gen_stack_pointer_dec (GEN_INT (-4096))); - emit_insn (gen_stack_pointer_dec (GEN_INT (4096 - size))); + emit_insn (gen_stack_pointer_inc (GEN_INT (4096))); + emit_insn (gen_stack_pointer_inc (GEN_INT (size - 4096))); } else { rtx reg = gen_rtx_REG (Pmode, 1); - emit_move_insn (reg, GEN_INT (-size)); - emit_insn (gen_stack_pointer_dec (reg)); + emit_move_insn (reg, GEN_INT (size)); + emit_insn (gen_stack_pointer_inc (reg)); } } } @@ -10414,7 +10402,7 @@ emit_and_preserve (rtx seq, rtx reg, rtx = gen_rtx_MEM (word_mode, plus_constant (stack_pointer_rtx, SPARC_STACK_BIAS + offset)); - emit_insn (gen_stack_pointer_dec (GEN_INT (size))); + emit_insn (gen_stack_pointer_inc (GEN_INT (-size))); emit_insn (gen_rtx_SET (VOIDmode, slot, reg)); if (reg2) emit_insn (gen_rtx_SET (VOIDmode, --- gcc-4.7.2/gcc/reorg.c.~1~ 2012-02-11 10:00:42.000000000 +0100 +++ gcc-4.7.2/gcc/reorg.c 2012-10-06 14:49:22.000000000 +0200 @@ -3466,9 +3466,8 @@ relax_delay_slots (rtx first) reorg_redirect_jump (insn, other_target); } - /* Now look only at cases where we have filled a delay slot. */ - if (!NONJUMP_INSN_P (insn) - || GET_CODE (PATTERN (insn)) != SEQUENCE) + /* Now look only at cases where we have a filled delay slot. */ + if (!NONJUMP_INSN_P (insn) || GET_CODE (PATTERN (insn)) != SEQUENCE) continue; pat = PATTERN (insn); @@ -3528,9 +3527,8 @@ relax_delay_slots (rtx first) } /* Now look only at the cases where we have a filled JUMP_INSN. */ - if (!JUMP_P (XVECEXP (PATTERN (insn), 0, 0)) - || ! (condjump_p (XVECEXP (PATTERN (insn), 0, 0)) - || condjump_in_parallel_p (XVECEXP (PATTERN (insn), 0, 0)))) + if (!JUMP_P (delay_insn) + || !(condjump_p (delay_insn) || condjump_in_parallel_p (delay_insn))) continue; target_label = JUMP_LABEL (delay_insn);