On targets such as sparc, where ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM, some of the invariants currently built into DSE simply do not hold.
Unlike how DSE assumes, we will in fact see stores to frame pointer relative addresses for setting up outgoing arguments to a CALL. The result is that DSE can eliminate stores that setup those arguments. Two test cases and a DSE debugging dump for one of them can be found at: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52684 Richard and Kenneth, can you take a look at this? The patch is against the 4.7 branch, which is where I've been tracking this down. I'm currently running it through a regstrap and a glibc build (the latter of which is where I originally saw this problem) Thanks. 2012-05-01 David S. Miller <da...@davemloft.net> PR target/53684 * dse.c (scan_insn): When the frame pointer is used as the argument pointer, mark non-const calls as frame_read. --- gcc/dse.c~ 2012-05-01 20:27:48.163611555 -0700 +++ gcc/dse.c 2012-05-02 01:03:19.450719154 -0700 @@ -2646,10 +2646,17 @@ scan_insn (bb_info_t bb_info, rtx insn) } else - /* Every other call, including pure functions, may read any memory - that is not relative to the frame. */ - add_non_frame_wild_read (bb_info); - + { + /* Every other call, including pure functions, may read any memory + that is not relative to the frame. */ + add_non_frame_wild_read (bb_info); +#if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM + /* If the target uses the frame pointer as the argument + pointer, then we will encounter frame relative stores + that setup outgoing arguments to a function. */ + insn_info->frame_read = true; +#endif + } return; }