On Tue, Apr 15, 2008 at 6:27 AM, Ian Lance Taylor <[EMAIL PROTECTED]> wrote: > Jim Wilson <[EMAIL PROTECTED]> writes: > > > It seems odd that cfgrtl allows a conditional trap inside a basic block, > > but not an unconditional trap. The way things are now, it means we need > > to fix up the basic blocks after running combine or any other pass that > > might be able to simplify a conditional trap into an unconditional trap. > > > > I can work around this in the IA64 port. For instance I could use > > different patterns for conditional and unconditional traps so that one > > can't be converted to the other. Or I could try to hide the conditional > > trap inside some pattern that doesn't get expanded until after reload. > > None of these solutions seems quite right. > > > > But changing the basic block tree during/after combine doesn't seem > > quite right either. > > > > The other solution would be to fix cfgbuild to treat all trap > > instructions are control flow insns, instead of just the unconditional > > ones. I'm not sure why it was written this way though, so I don't know > > if this will cause other problems. I see that sibling and noreturn > > calls are handled the same way as trap instructions, implying that they > > are broken too. > > I think the current cfgbuild behaviour is just to avoid putting a > barrier in the middle of a basic block. A conditional trap > instruction is not necessarily a control flow instruction for the > compiler--it's similar to a function call which may or may not return. > An unconditional trap is similar to a function call which is known to > not return. > > I guess the difference is that combine can't turn a function call > which may or may not return into a function call which will not > return. > > Since traps are uncommon, and since you can't do a lot of optimization > around them anyhow, it's probably OK to make them always return true > from control_flow_insn_p. At least it's worth trying to see if > anything breaks.
A similar issue exists on the tree level when you try to fix PR35468 the "right" way. Consider char *const line = "/dev/ptyXX"; line[8] = 1; ... the assignment to line[8] is a "conditional trap" which ccp transforms into "/dev/ptyXX"[8] = 1; which is invalid GIMPLE and we'd like to fold into a un-conditional trap (__builtin_trap(), as done elsewhere). Of course now you need to start splitting basic blocks in fold_stmt or teach its callers that it may need to cleanup themselves... both is kind of ugly, but of course we don't want every store to end a basic block either... Richard.