I'm looking for help with an if-convert problem. I have a local arm based target, but with most of the conditional execution patterns disabled. Before the first if-conversion pass we have the following RTL:
(set (reg2) (const_int 0)) (set (CC) (compare (reg1) (const_int 0))) (jump if (CC) (label_ref 1) (set (reg2) (const_int 1)) (label 1) (jump if (CC) (label_ref 2)) ... The CE1 pass recognises the first conditional branch as a store-flag sequence, and replaces it with a abs/sub/shift sequence: (set (CC) (compare (reg1) (const_int 0))) (parallel (set (reg2) (abs (reg1))) (clobber (CC))) (sub/shift) (jump if (CC) (label_ref 2)) The problem is that it does this without any liveness information. An ARM the abs instruction clobbers the condition code register (CC). The CC was live over this block and is still needed for the second conditional branch. Things go rapidly downhill from there. I can't reproduce the bug with FSF sources, However I believe this is a latent bug that could effect any targets that use specific hard registers. CC is the most common example, but I guess this could also happen with other fixed registers (e.g. multipliers with fixed output registers). Ideally I guess we'd do something similar to combine, and use life information to avoid clobbering useful values. However we don't have life info, and I guess calculating it would be expensive. The best compromise I've been able to come up with is the scan the replacement sequence for new sets/clobbers of hard registers, and reject the replacement if this occurs. This scanning is fairly ugly, but quicker than full life analysis and hopefully won't cause too many pessimizations, though I'd have to check x86. Any suggestions? Paul