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

Reply via email to