A first patch to use the reasoning in ConstraintElimination to simplify
sub with overflow to a regular sub, if the operation is guaranteed to
not overflow.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Would it be sufficient to only replace the m_ExtractValue<1>? I believe that's what we usually do. (Would also work if only the extractvalue is dominated.)
And leave the removal of the actual intrinsic call to instcombine (or some other existing transform)? If that's what we do elsewhere I think it should work, the current placement in the regular optimization pipeline means we run instcombine shortly after ConstraintElimiantion.
Yeah, that's what I had in mind. Though checking now, it looks like both CVP (https://github.com/llvm/llvm-project/blob/72831a592edf1bdcca15354181867079a17d4f76/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp#L572) and SimplifyIndVars (https://github.com/llvm/llvm-project/blob/72831a592edf1bdcca15354181867079a17d4f76/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp#L423) do replace the with.overflow intrinsic itself, so maybe it's fine as is.
Those examples also do eraseFromParent(). I don't know if there's any official guideline for the behavior, but cleaning up dead values here makes it less likely that things will break if some other pass gets inserted in the pipeline between this and the next round of instcombine.
That's a good point, thanks! I updated the code to remove both the extracts and the intrinsic, if possible.
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | ||
---|---|---|
537–538 | This pre-condition is not correct - if A is 0 and B is SMIN for a given width, that overflows. Double-check to make sure I got the right pattern, but we should have a test like this: |
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | ||
---|---|---|
537–538 | Thanks, this needs to check if B >= 0, which also implies A >= 0. I added additional tests in 1911843c3126 based on the shared alive2 code (I think the one you shared had different compares for %c.2 in @src and @tgt, so the verification failure was about that, here's a slightly updated one: https://alive2.llvm.org/ce/z/L_K648) |
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | ||
---|---|---|
537–538 | Ah, yes - I messed up that alive code. %a_is_neg = icmp slt i8 %a, 0 %b_is_neg = icmp slt i8 %b, 0 %same_sign = icmp eq i1 %a_is_neg, %b_is_neg https://alive2.llvm.org/ce/z/D-uuBW I'm not sure how to best translate that to the getConstraint() framework. |
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | ||
---|---|---|
537–538 | I think we would have to separately check for s>=0 and s<0 case. I could further extend this patch or do it as follow up. |
LGTM
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | ||
---|---|---|
537–538 | A different patch is probably better. |
This pre-condition is not correct - if A is 0 and B is SMIN for a given width, that overflows.
Double-check to make sure I got the right pattern, but we should have a test like this:
https://alive2.llvm.org/ce/z/t9G3TQ