-
Notifications
You must be signed in to change notification settings - Fork 11.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IR programs printing incorrect results after being compiled with -O0 #40003
Comments
Not sure if this is the whole problem, but TargetLowering::SimplifySetCC(): This doesn't check to see if the operands are i1 (bool), so the shift produces poison/undef. We don't have this problem in IR because instcombine knows that add/sub of i1 is really an 'xor': if (Ty->isIntOrIntVectorTy(1)) |
That might've been better stated as: Ie, why is a shift better than a subtract here? I took out the fold completely, and no regression tests fail, but I guess it's better to guard against the bug as a 1st step. Note that just adding the transforms for 'add/sub i1 -> xor i1' is not enough to fix the bug because we can reach the setcc first. (But adding those transforms might be a good change independently.) |
TBH, if this causes no test regressions I'd vote for removing it entirely straight away. |
Hello Sanjay, I'm not sure whether X<<1 returns undef/poison in SelDAG (It is poison in IR, but SelDag is a lower level language), but I agree that the transformation can be the source of the bug, as SelDag and IR seems to share the semantics of arithmetic operations. I found that disabling the folding fixes 8 buggy cases including the one in the text but 3 cases still remain: 1673800.ll: prints 0 All of them should print 1. p.s: 66787.ll should print 15, and disabling '(Z-X) == X' to 'Z == X<<1' correctly fixes it. I said that all programs should run 1 at comment #1, but 66787.ll was an exception, sorry. |
SDAG has poison because it propagates the wrapping/exact flags from IR. As a practical matter, it is harder to see poison/undef problems in this layer because:
Not yet - but let's take this 1 step at a time. I think there's no question about the 1st fix, so I have committed that here: |
I added some tests to see if there was anything else doing the same thing. There isn't, and there is a minor potential benefit to the shift (which gets translated to add somewhere in X86ISelDAGToDAG.cpp), so I think it's ok to keep. |
That was here: |
This is the same problem from what I see. The code that was just fixed is duplicated later for the commuted case: This whole "function" is a giant mess, so I'll see if I can reduce the code duplication. |
All attached examples should be fixed after: Feel free to reopen if that's not correct. Side note about fuzzing for LLVM bugs: $ clang -O2 test.c -S -emit-llvm -Xclang -disable-llvm-optzns -o unoptimized_ir.ll A lot of people get that 1st step wrong: you want clang to create an IR file that allows optimization by the backend, but skip intermediate optimization. That doesn't happen if you use "-O0 -emit-llvm" with clang. |
Thank you for the advice! :) |
mentioned in issue llvm/llvm-bugzilla-archive#42580 |
Extended Description
Consider this program:
This program should print 1, but it prints 0 after being compiled with -O0.
$ clang --version
clang version 9.0.0 (https://github.com/llvm-mirror/clang.git 23cffd780f5647d02c6c12491f9b2c928757c798) (https://github.com/llvm-mirror/llvm.git 903a569)
Target: x86_64-unknown-linux-gnu
$ clang -O0 -o a.out 2332174.ll
$ ./a.out
0
I attach a few more programs which should print 1 but they print 0.
The text was updated successfully, but these errors were encountered: