The following code is miscompiled by the current clang trunk on x86_64-linux-gnu at -Os and above in both 32-bit and 64-bit modes. This is a regression from 3.7.x. $ clang-trunk -v clang version 3.8.0 (trunk 257078) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/tools/bin Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9.3 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.2.1 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4.7 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6.4 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7.3 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.2.1 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Candidate multilib: x32;@mx32 Selected multilib: .;@m64 $ $ clang-trunk -O1 small.c; ./a.out 0 $ clang-3.7.0 -Os small.c; ./a.out 0 $ $ clang-trunk -Os small.c; ./a.out $ -------------------------------------------- int printf (const char *, ...); char a; int b, c; int main () { int d = c = 1; for (; a < 1; a++) { char e; for (;;) { e = ~((c || c) | ~(b && -d)); if (e < c) { printf ("%d\n", b); c = 1; } break; } } return 0; }
Bisection points to r249687.
define i32 @main(i32 %i3) { %i2 = icmp ne i32 1, 0 %lor.ext = zext i1 %i2 to i32 %tobool4 = icmp eq i32 %i3, 0 %sel = select i1 %tobool4, i32 255, i32 254 %or = or i32 %sel, %lor.ext %neg6 = xor i32 %or, 255 %cmp9 = icmp slt i32 %neg6, 1 br i1 %cmp9, label %if, label %exit if: ret i32 1 exit: ret i32 0 } $ ./opt 26071small.ll -S |./llc -o - -mtriple=x86_64-apple-darwin |./clang -x assembler - ; ./a.out ; echo $? 1 $ ./opt -sccp -bdce 26071small.ll -S |./llc -o - -mtriple=x86_64-apple-darwin |./clang -x assembler - ; ./a.out ; echo $? 0
Did this get fixed?
(In reply to comment #3) > Did this get fixed? No, this is still broken as of r259529.
We should probably revert r249687 in the meanwhile.
Hi, Sorry, this seemed to fly by me. I'm surprised my recent bug fix to this code didn't sort this; I will investigate with urgency tomorrow. James
Hi, This code is indeed wrong. What's happening is that ComputeKnownZeroes is telling us that all bits except the LSB are zero. We're then deciding that only the LSB needs to be demanded from the icmp's inputs. This is where we're wrong - we're assuming that after simplification the bits that were known zero will continue to be known zero. But they're not - during trivialization the upper bits get changed (because an XOR isn't shrunk), so the icmp fails. The fault is in demandedbits - its contract does clearly state that a non-demanded bit may either be zero or one. I will revert the change and think about how to do this better. James
Reverted in r259649. I had to remove a LoopVectorize test that is now failing, so I will need to go think about how to implement this in a sane way.