aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-03-18 18:27:45 +0800
committerGitHub <noreply@github.com>2024-03-18 18:27:45 +0800
commit38a44bdc93db5b00310230f6542df39017b9a41b (patch)
tree655c97732268b02f8c034601fb6f06a48f1bfbd9 /llvm/lib/CodeGen/CodeGenPrepare.cpp
parentf362e12aab9ce07b836a2622fc987cda8b6ab6f8 (diff)
downloadllvm-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.cpp36
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;
}