-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[ConstraintElimination] A miscompile in presence of shl nuw nsw
and llvm.umin
#78621
Comments
From the debug log, I suspect that we're using the unsigned constraint system to prove a signed fact for some reason. cc @fhahn |
Okay, this is an interesting case. We are adding an Then we are checking whether a solution of these constraints plus This is "correct" in the sense that if that umin call returns a non-poison result, then @dtcxzyw @fhahn This makes me think that the way we are currently adding facts for MinMaxIntrinsic (and I guess abs as well) is pretty fundamentally incorrect, because it effectively imposes a constraint that the umin operation returns a well-defined value. Any thoughts on how to fix this without dropping support for them entirely? |
(The difference between shl and mul in the reproducer is because ValueTracking apparently currently doesn't know that mul nuw nsw is non-negative, but knows that shl nuw nsw is.) |
Can we conservatively check these intrinsics using |
If it's not too complicated, I think a better solution would be to only add the intrinsic constraints when the result variable is added to the constraint system. |
One way to do that would be to check the uses of the intrinsic and find all the branches that it feeds, and add it as fact for the successors. |
@dtcxzyw Do you plan to submit a PR for this issue? |
I will post a patch later. |
Tests with umin where the result may be poison for #78621.
I've pushed a fix that only adds the facts if the result is guaranteed to not be poison so the mis-compile is fixed. I also added a TODO to improve things if possible. Reopening so we can pick the fix for the release branch |
@fhahn Why does your fix only do this for min/max but not abs? Can't it have the same problem? |
I wasn't able to come up with a problematic test case so far for |
@fhahn I'm not familiar with how this pass works, so I have a question: will this pass still use min/max/etc. to infer facts about the arguments of those intrinsics? I'm just a bit confused by the terminology: I see that it adds "constraints" based on things like |
Constraints for icmps will only be added in branches that the icmp dominates (or code that an assume with an icmp dominates). The intrinsic handling was a bit special in that constraints are added unconditionally. |
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
/pull-request #80260 |
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
Tests with umin where the result may be poison for llvm#78621. (cherry picked from commit c83180c)
The result of umin may be poison and in that case the added constraints are not be valid in contexts where poison doesn't cause UB. Only queue facts for min/max intrinsics if the result is guaranteed to not be poison. This could be improved in the future, by only adding the fact when solving conditions using the result value. Fixes llvm#78621. (cherry picked from commit 3d91d96)
The following commit: 71f56e4
Triggered this miscompile: https://alive2.llvm.org/ce/z/oBg-u8
Now
opt -passes=constraint-elimination -S
turnsinto
Given this debug output:
I'm not 100% sure if the aforementioned patch causes the miscompile, of if it merely triggers it on this specific reproducer. The fact that something like
-1 * %call4 <= 0
is reported as a "dominating constraint" seems suspicious to a person who's not familiar with the logic of ConstraintElimination and it doesn't look directly related to that patch. However, if I replace theshl nuw nsw i32 %arg, 3
withmul nuw nsw i32 %arg, 8
, the miscompile doesn't happen: https://alive2.llvm.org/ce/z/EL2bCh.The text was updated successfully, but these errors were encountered: