I've seen a number of execution failures with the soon-to-be submitted ARCompact port in the context of gcc 4.8, which where down to an rtlanal.c:dead_or_set_p problem, e.g.: gcc.c-torture/execute/builtin-bitops-1.c -O1
As the comment at the top of dead_or_set_p states, this function should return true if a register is dies in INSN or is entirely set. A COND_EXEC does not set at all if the condition is not true; for the purposes of dead_or_set_p, it should be treated like a partial set or a REG_INC, i.e. the COND_EXEC and its contents should be disregarded. Yet dead_or_set_regno_p, a helper function of dead_or_set_p, instead processes a COND_EXEC as if it always took place. I see this was introduced in the 2000-04-07 mega-patch that introduced COND_EXEC. Certainly in lots of other places the right thing is to look inside the COND_EXEC, but not here. Fixed with the attached patch. Bootstrapped on ia64-unknown-linux-gnu.
2011-11-27 Joern Rennecke <joern.renne...@embecosm.com> * rtlanal.c (dead_or_set_regno_p): Fix COND_EXEC handling. Index: rtlanal.c =================================================================== --- rtlanal.c (revision 191467) +++ rtlanal.c (working copy) @@ -1701,8 +1701,9 @@ pattern = PATTERN (insn); + /* If a COND_EXEC is not executed, the value survives. */ if (GET_CODE (pattern) == COND_EXEC) - pattern = COND_EXEC_CODE (pattern); + return 0; if (GET_CODE (pattern) == SET) return covers_regno_p (SET_DEST (pattern), test_regno);