diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-10-15 08:17:50 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-15 08:17:50 +0800 |
commit | 637e81f8adfe725c73aeafa4c2315d962be4770d (patch) | |
tree | 3a1f3b348f9be65d26cd85213dddd32914ae9b47 /llvm/lib/CodeGen/CodeGenPrepare.cpp | |
parent | 8225938a73406f26e599c7a55fa019422fe18369 (diff) | |
download | llvm-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.cpp | 28 |
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; } |