aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
authorVolodymyr Vasylkun <vvmposeydon@gmail.com>2024-08-21 23:15:24 +0100
committerGitHub <noreply@github.com>2024-08-21 23:15:24 +0100
commitbe7d08cd59b0f23eea88e791b2413b44301949d3 (patch)
tree26b8612b91d714040d635be5346371d3545b589e /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
parent5c7ae42c526b21acf65ab4b017d0a5fd4ac654a1 (diff)
downloadllvm-be7d08cd59b0f23eea88e791b2413b44301949d3.zip
llvm-be7d08cd59b0f23eea88e791b2413b44301949d3.tar.gz
llvm-be7d08cd59b0f23eea88e791b2413b44301949d3.tar.bz2
[InstCombine] Fold `sext(A < B) + zext(A > B)` into `ucmp/scmp(A, B)` (#103833)
This change also covers the fold of `zext(A > B) - zext(A < B)` since it is already being canonicalized into the aforementioned pattern. Proof: https://alive2.llvm.org/ce/z/AgnfMn
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index dd4a640..d7758b5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1626,6 +1626,26 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
A->getType()->isIntOrIntVectorTy(1))
return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ // sext(A < B) + zext(A > B) => ucmp/scmp(A, B)
+ ICmpInst::Predicate LTPred, GTPred;
+ if (match(&I,
+ m_c_Add(m_SExt(m_c_ICmp(LTPred, m_Value(A), m_Value(B))),
+ m_ZExt(m_c_ICmp(GTPred, m_Deferred(A), m_Deferred(B))))) &&
+ A->getType()->isIntOrIntVectorTy()) {
+ if (ICmpInst::isGT(LTPred)) {
+ std::swap(LTPred, GTPred);
+ std::swap(A, B);
+ }
+
+ if (ICmpInst::isLT(LTPred) && ICmpInst::isGT(GTPred) &&
+ ICmpInst::isSigned(LTPred) == ICmpInst::isSigned(GTPred))
+ return replaceInstUsesWith(
+ I, Builder.CreateIntrinsic(
+ Ty,
+ ICmpInst::isSigned(LTPred) ? Intrinsic::scmp : Intrinsic::ucmp,
+ {A, B}));
+ }
+
// A+B --> A|B iff A and B have no bits set in common.
WithCache<const Value *> LHSCache(LHS), RHSCache(RHS);
if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I)))