https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63404
Andi Kleen <andi-gcc at firstfloor dot org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|middle-end |target
--- Comment #2 from Andi Kleen <andi-gcc at firstfloor dot org> ---
The switch is miscompiled and destroys the flags register in the middle of a
comparison:
.LVL2:
.loc 1 49 0
cmpl $2, %eax #, seq
je .L5 #,
shrb $2, %r12b #, D.32130 <-------- BAD1
andl $1, %r12d #, D.32130 <-------- BAD2
jbe .L24 #,
cmpl $4, %eax #, seq
je .L7 #,
cmpl $8, %eax #, seq
jne .L4 #,
gcc 4.9 creates the same code except for BAD1/BAD2. These two
JBE relies on CF/ZF being preserved, but SHR can overwrite ZF/CF,
which breaks the JBE after the CMP
So somehow the backend lost track of these two flag bits.