Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Please provide an alive proof and add tests for other predicates as well, as well as negative tests (e.g. 2 instead of 1, which should not fold).
https://alive2.llvm.org/ce/z/DJqxNZ try to add alive, please correct me if it's not correct
Move this to InstSimplify rather than InstCombine. It should handle both equality preds at least (eq and ne). You should not create a fake instruction - create the expected constant directly.
I think we can generalize the transform at least in one direction - the constant does not have to be 1:
https://alive2.llvm.org/ce/z/bPYNJT
(not sure if there's some other relationship for non-equality predicates)
iupdate to InstSimplify, transform:
(sub nsw|nuw C, X) == X, C is odd --> false
https://alive2.llvm.org/ce/z/dyn2Z2
(sub nsw|nuw C, X) != X, C is odd --> true
https://alive2.llvm.org/ce/z/5aSkqc
(sub 1, X) == X --> false
(sub 1, X) != X --> true
https://alive2.llvm.org/ce/z/DJqxNZ
I think we can generalize the transform at least in one direction - the constant does not have to be 1:
https://alive2.llvm.org/ce/z/bPYNJT
(not sure if there's some other relationship for non-equality predicates)
I am trying to understand the example, get odd constant value from more instructions(>1), I don't know how to implement it, any suggestions?
The proof just shows that the transform is valid for any value with low-bit cleared.
If the value is a constant, then it is easy to detect. If the value is not constant, then we have to try more expensive (in compile-time) analysis - see ValueTracking's computeKnownBits() for example.
If we do not have a real-world example that shows the more expensive transform is needed, then we should not add it. In other words, the patch is mostly fine as implemented. But I do not understand why we have no-wrap requirements. The transform is correct without those:
https://alive2.llvm.org/ce/z/h4ZFVD
llvm/test/Transforms/InstCombine/icmp-sub.ll | ||
---|---|---|
570 ↗ | (On Diff #457491) | No need to include "entry" label in a minimum test like this. |
572 ↗ | (On Diff #457491) | What happens if %sub and %x are swapped in this test? |
576 ↗ | (On Diff #457491) | Change this to a vector type to confirm that the transform works in that case too. We should have one test where the vector constant includes a "poison" element too. |
587 ↗ | (On Diff #457491) | We need at least one negative test with an even constant. That shows that the transform is not happening when it should not. |
If we do not have a real-world example that shows the more expensive transform is needed, then we should not add it. In other words, the patch is mostly fine as implemented. But I do not understand why we have no-wrap requirements. The transform is correct without those:
https://alive2.llvm.org/ce/z/h4ZFVD
Actually, I'm not sure if just using srem(2) is correct.
I think it would be a little more efficient/readable to code this as "*C & 1".
But we need to be certain that the transform is correct to proceed. Do you have a counter-example that shows an incorrect result?
llvm/lib/Analysis/InstructionSimplify.cpp | ||
---|---|---|
3310 | Can we use knownbits here instead to support non-uniform constant vectors? I'm never very clear on when we're allowed to use value tracking in instsimplify as its more expensive.... |
- Did you determine that the transform is valid without nsw/nuw?
- My request for a vector test with poison element was not handled. Please mark inline questions as completed when they are answered.
- The tests should be in the tests/Transforms/InstSimplify directory, and the RUN line should only use -instsimplify.
llvm/lib/Analysis/InstructionSimplify.cpp | ||
---|---|---|
3308–3309 | Reduce to match() with m_Specific()? | |
3310 | Yes, I mentioned that in an earlier comment. I think we could handle the non-uniform constant pattern even without knownbits - check the compare of a constant expression? But I'd say let's do that as a follow-up to keep this patch simpler. |
llvm/lib/Analysis/InstructionSimplify.cpp | ||
---|---|---|
3254–3261 | Can you add this match inside of simplifyICmpWithBinOpOnLHS()? Then the swapped pattern is handled automatically. | |
3308 | The nullptr and equality checks are redundant - that is handled by the match(). | |
llvm/test/Transforms/InstSimplify/icmp.ll | ||
215 | Please pre-commit the baseline tests and then update this patch so it shows the diffs. |
LGTM
llvm/lib/Analysis/InstructionSimplify.cpp | ||
---|---|---|
3134 | This can be shortened like the code above: return getFalse(ITy); ... return getTrue(ITy); |
llvm/lib/Analysis/InstructionSimplify.cpp | ||
---|---|---|
3134 | ||
3134 | https://reviews.llvm.org/rG456c7ef68e13b9dedd12a2333e01b6fdbc534b0a done, sorry I didn't read it carefully |
This can be shortened like the code above: