The following testcase is miscompiled on x86_64-linux at -O2. Before global alloc/reload, the interesting part of code is: (reg:DI %rax) = (call _Znwm (1)) (reg:DI 81) = (reg:DI %rax) ... (reg:DI %rdi) = (reg:DI 81) (call _ZN2C1C1ERK2C3S2_S2_RPS1_ (%rdi, ...)) - may throw, EH pad .Leh ... (reg:DI %rdi) = (reg:DI 81) ... (barrier) .Leh: (reg:DI %rdi) = (reg:DI 81) (call _ZdlPv (%rdi))
Now, as the register preassure is pretty high, there don't appear to be any free usable call saved registers for pseudo 81, so global alloc assigns pseudo 81 into (reg:DI %r10), which is call clobbered. Then reload saves it into stack before the _ZN2C1C1ERK2C3S2_S2_RPS1_ call and restores it from the stack slot after the call. But doesn't restore it on the EH path as well. So we end up with: (reg:DI %rax) = (call _Znwm (1)) (reg:DI %r10 (81)) = (reg:DI %rax) ... (reg:DI %rdi) = (reg:DI %r10 (81)) (mem:DI %rsp+24) = (reg:DI %r10 (81)) (call _ZN2C1C1ERK2C3S2_S2_RPS1_ (%rdi, ...)) - may throw, EH pad .Leh (reg:DI %r10 (81)) = (mem:DI %rsp+24) ... (reg:DI %rdi) = (reg:DI %r10 (81)) ... (barrier) .Leh: (reg:DI %rdi) = (reg:DI %r10 (81)) (call _ZdlPv (%rdi)) As this is a reload bug, it is not reproduceable on != 3.4.x compilers I have tried, which doesn't mean the bug is present on 3.4.x only though. -- Summary: Miscompilation due to reloading of a var that is also used in EH pad Product: gcc Version: 3.4.5 Status: UNCONFIRMED Severity: critical Priority: P2 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at redhat dot com CC: gcc-bugs at gcc dot gnu dot org GCC target triplet: x86_64-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23478