diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-03-18 18:27:45 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-18 18:27:45 +0800 |
commit | 38a44bdc93db5b00310230f6542df39017b9a41b (patch) | |
tree | 655c97732268b02f8c034601fb6f06a48f1bfbd9 /llvm/lib/CodeGen/CodeGenPrepare.cpp | |
parent | f362e12aab9ce07b836a2622fc987cda8b6ab6f8 (diff) | |
download | llvm-38a44bdc93db5b00310230f6542df39017b9a41b.zip llvm-38a44bdc93db5b00310230f6542df39017b9a41b.tar.gz llvm-38a44bdc93db5b00310230f6542df39017b9a41b.tar.bz2 |
[CodeGenPrepare] Reverse the canonicalization of isInf/isNanOrInf (#81572)
In commit
https://github.com/llvm/llvm-project/commit/2b582440c16c72b6b021ea5c212ceda3bdfb2b9b,
we canonicalize the isInf/isNanOrInf idiom into fabs+fcmp for better
analysis/codegen (See also the discussion in
https://github.com/llvm/llvm-project/pull/76338).
This patch reverses the fabs+fcmp to `is.fpclass`. If the `is.fpclass`
is not supported by the target, it will be expanded by TLI.
Fixes the regression introduced by
https://github.com/llvm/llvm-project/commit/2b582440c16c72b6b021ea5c212ceda3bdfb2b9b
and
https://github.com/llvm/llvm-project/pull/80414#issuecomment-1936374206.
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index bece70a..921a5b7 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -1943,6 +1943,39 @@ static bool swapICmpOperandsToExposeCSEOpportunities(CmpInst *Cmp) { return false; } +static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI, + const DataLayout &DL) { + FCmpInst *FCmp = dyn_cast<FCmpInst>(Cmp); + if (!FCmp) + return false; + + // Don't fold if the target offers free fabs and the predicate is legal. + EVT VT = TLI.getValueType(DL, Cmp->getOperand(0)->getType()); + if (TLI.isFAbsFree(VT) && + TLI.isCondCodeLegal(getFCmpCondCode(FCmp->getPredicate()), + VT.getSimpleVT())) + return false; + + // Reverse the canonicalization if it is a FP class test + auto ShouldReverseTransform = [](FPClassTest ClassTest) { + return ClassTest == fcInf || ClassTest == (fcInf | fcNan); + }; + auto [ClassVal, ClassTest] = + fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(), + FCmp->getOperand(0), FCmp->getOperand(1)); + if (!ClassVal) + return false; + + if (!ShouldReverseTransform(ClassTest) && !ShouldReverseTransform(~ClassTest)) + return false; + + IRBuilder<> Builder(Cmp); + Value *IsFPClass = Builder.createIsFPClass(ClassVal, ClassTest); + Cmp->replaceAllUsesWith(IsFPClass); + RecursivelyDeleteTriviallyDeadInstructions(Cmp); + return true; +} + bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) { if (sinkCmpExpression(Cmp, *TLI)) return true; @@ -1959,6 +1992,9 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) { if (swapICmpOperandsToExposeCSEOpportunities(Cmp)) return true; + if (foldFCmpToFPClassTest(Cmp, *TLI, *DL)) + return true; + return false; } |