-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[IndVarSimplify] WRONG code with i128 and -replexitval=always #83268
Comments
Are you sure IndVarSimplify is at fault here? Everything looks correct to me here: ; %extract.t9 = i8 0
; %d.promoted = i128 0
%0 = add i128 %d.promoted, -1 ; %0 = i128 -1
%1 = mul i8 %extract.t9, 85 ; %1 = i8 0
%2 = add i8 %1, 85 ; %2 = i8 85
%3 = zext i8 %2 to i128 ; %3 = i128 85
%umin = call i128 @llvm.umin.i128(i128 %0, i128 %3) ; %umin = i128 85
%4 = sub i128 %0, %umin ; %4 = i128 -86 Maybe this just exposes an s390x backend problem? I can't reproduce this on x86. |
Ah! I think you are actually right (thanks for helping out) - this could be an i128 related problem in the backend. If I used "llc -zEC12" for the backend part and then assemled/linked, it prints the correct result. If I instead do "llc -z13" it prints 0 (wrong). I think it is going wrong in the preheader:
llc -mtriple=s390x-linux-gnu -mcpu=z13 -O3 wrong0.ll -o wrong0.s CC @uweigand |
Ah, I see. Common code is replacing a USUBSAT with a USUBO and is inspecting the overflow result. We're currently generating that overflow result via the VSCBIQ instruction for i128, but that actually has inverted semantics: it sets the result to 1 if there was no carry out from the subtraction, and it sets the result to 0 if there was a carry out. Common code expects it exactly the other way round. Current code still works when feeding the result of a USUBO into a USUBO_CARRY, because both use the same inverted sense. But if LLVM common code inspects the overflow result for its own purposes, this will break. I guess we'll have to emit explicit inversion operations for USUBO and USUBO_CARRY (which should cancel out when used in combination). I'll have a look. |
Hi @JonPsson1, can you check whether this patch fixes the problem for you? Thanks! |
@uweigand Yes, this fixes my test case so that it now produces the expected result. |
Committed as d9c31ee. |
Sorry, had to revert after a mis-applied merge. Will re-test and reapply. |
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: #83268
Agreed, this should be backported. |
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: llvm#83268
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: llvm#83268
What was the commit hash of the re-applied version? |
/cherry-pick 335f365 |
Failed to cherry-pick: 335f365 https://github.com/llvm/llvm-project/actions/runs/8411476158 Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request |
/cherry-pick d9c31ee |
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: llvm#83268 (cherry picked from commit d9c31ee)
/pull-request #86475 |
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: llvm#83268
Manual backport PR at #86491 |
We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: #83268
This program should print -86:
With the option -replexitval=always, the IndVarSimplifyPass does something quite weird that I don't understand. It seems it is trying to compute the final value that is stored in the preheader, but that computation is '0', so it must be wrong.
clang -O3 -march=z15 wrong0.i -o ./a.out <> clang -O3 -march=z15 wrong0.i -o ./a.out -mllvm -replexitval=always
@nikic @xortator @uweigand
The text was updated successfully, but these errors were encountered: