diff options
author | Volodymyr Vasylkun <vvmposeydon@gmail.com> | 2024-08-21 23:15:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-21 23:15:24 +0100 |
commit | be7d08cd59b0f23eea88e791b2413b44301949d3 (patch) | |
tree | 26b8612b91d714040d635be5346371d3545b589e /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | |
parent | 5c7ae42c526b21acf65ab4b017d0a5fd4ac654a1 (diff) | |
download | llvm-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.cpp | 20 |
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))) |