aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-10-15 08:17:50 +0800
committerGitHub <noreply@github.com>2024-10-15 08:17:50 +0800
commit637e81f8adfe725c73aeafa4c2315d962be4770d (patch)
tree3a1f3b348f9be65d26cd85213dddd32914ae9b47 /llvm/lib/CodeGen/CodeGenPrepare.cpp
parent8225938a73406f26e599c7a55fa019422fe18369 (diff)
downloadllvm-637e81f8adfe725c73aeafa4c2315d962be4770d.zip
llvm-637e81f8adfe725c73aeafa4c2315d962be4770d.tar.gz
llvm-637e81f8adfe725c73aeafa4c2315d962be4770d.tar.bz2
Reland `[CodeGenPrepare] Convert `ctpop(X) ==/!= 1` into `ctpop(X) u</u> 2/1` (#111284)` (#111998)
Relands #111284. Test failure with stage2 build has been fixed by https://github.com/llvm/llvm-project/pull/111946. Some targets have better codegen for `ctpop(X) u< 2` than `ctpop(X) == 1`. After https://github.com/llvm/llvm-project/pull/100899, we set the range of ctpop's return value to indicate the argument/result is non-zero. This patch converts `ctpop(X) ==/!= 1` into `ctpop(X) u</u> 2/1` in CGP to fix https://github.com/llvm/llvm-project/issues/95255.
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 3e09fba..86f2829 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2111,6 +2111,31 @@ bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
return false;
}
+/// Some targets have better codegen for `ctpop(X) u< 2` than `ctpop(X) == 1`.
+/// This function converts `ctpop(X) ==/!= 1` into `ctpop(X) u</u> 2/1` if the
+/// result cannot be zero.
+static bool adjustIsPower2Test(CmpInst *Cmp, const TargetLowering &TLI,
+ const TargetTransformInfo &TTI,
+ const DataLayout &DL) {
+ ICmpInst::Predicate Pred;
+ if (!match(Cmp, m_ICmp(Pred, m_Intrinsic<Intrinsic::ctpop>(), m_One())))
+ return false;
+ if (!ICmpInst::isEquality(Pred))
+ return false;
+ auto *II = cast<IntrinsicInst>(Cmp->getOperand(0));
+
+ if (isKnownNonZero(II, DL)) {
+ if (Pred == ICmpInst::ICMP_EQ) {
+ Cmp->setOperand(1, ConstantInt::get(II->getType(), 2));
+ Cmp->setPredicate(ICmpInst::ICMP_ULT);
+ } else {
+ Cmp->setPredicate(ICmpInst::ICMP_UGT);
+ }
+ return true;
+ }
+ return false;
+}
+
bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
if (sinkCmpExpression(Cmp, *TLI))
return true;
@@ -2130,6 +2155,9 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
if (foldFCmpToFPClassTest(Cmp, *TLI, *DL))
return true;
+ if (adjustIsPower2Test(Cmp, *TLI, *TTI, *DL))
+ return true;
+
return false;
}