Greetings! GCC is usually so perfect, that I hate to write, but ... I think I'm chasing down quite the bug in it and would appreciate some thought to the following.
The code that causes the bug looks like: if (ptr) { *ptr = 1; } This code evaluates, in the instruction set I am working with, into the following RTL: (set (cc0) (compare (reg 3) (reg 1))) (set (pc) (if-then-else (eq (cc0) (const_int 0)) (label_ref 258) (pc))) (set (mem (reg 3)) (reg 1)) (all modes are SI) This would be all fine and dandy, up until the if_convert modifications. if_convert() rightly decides that the store instruction is prime for a conditional execution conversion. Therefore, if_convert() transforms this code into: (cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1))) This, by itself, is a valid conversion. The problem is that when cond_exec_process_if_block calls merge_if_block(ce_info) to package up the changes and make them permanent, merge_if_block then calls merge_block which deletes not only the conditional jump statement (set (pc) ... etc.), but also the compare that set the conditions prior to the jump statement (see rtl_merge_blocks within cfgrtl.c). Hence instead of the working RTL, (set (cc0) (compare (reg 3) (reg 1))) (cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1))) I'm left with the broken RTL: (cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1))) Can someone tell me if I am missing something, or whether this really is a bug in GCC? Thanks! Dan