[PATCH] D128123: [SDAG] try to replace subtract-from-constant with xor
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 12 07:17:39 PDT 2022
spatel added a comment.
In D128123#3643672 <https://reviews.llvm.org/D128123#3643672>, @bjope wrote:
> Not sure really if this ends up as a regression or not, but with this source we can see some differences if for example using heaxagon or systemz as targets.
> (This example is related to doing sub->xor in instcombine so not exactly the patch in this review.)
Thanks for the example. The instcombine variation of this fold has a different problem that I noticed in another example.
Can you try the patch below and see if that fixes the regressions for your target?
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 535a7736454c..c51ce0e8d1c3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1966,13 +1966,6 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
}
- // If there's no chance any bit will need to borrow from an adjacent bit:
- // sub C, X --> xor X, C
- const APInt *Op0C;
- if (match(Op0, m_APInt(Op0C)) &&
- (~computeKnownBits(Op1, 0, &I).Zero).isSubsetOf(*Op0C))
- return BinaryOperator::CreateXor(Op1, Op0);
-
{
Value *Y;
// X-(X+Y) == -Y X-(Y+X) == -Y
@@ -2231,7 +2224,20 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
I, Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
{Builder.CreateNot(X)}));
- return TryToNarrowDeduceFlags();
+ if (Instruction *R = TryToNarrowDeduceFlags())
+ return R;
+
+ // If there's no chance any bit will need to borrow from an adjacent bit:
+ // sub C, X --> xor X, C
+ // Avoid this fold if the sub has no-wrap flags because that could be an
+ // information-losing transform that we cannot recover from.
+ const APInt *Op0C;
+ if (!I.hasNoSignedWrap() && !I.hasNoUnsignedWrap() &&
+ match(Op0, m_APInt(Op0C)) &&
+ (~computeKnownBits(Op1, 0, &I).Zero).isSubsetOf(*Op0C))
+ return BinaryOperator::CreateXor(Op1, Op0);
+
+ return nullptr;
}
/// This eliminates floating-point negation in either 'fneg(X)' or
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D128123/new/
https://reviews.llvm.org/D128123
More information about the llvm-commits
mailing list