aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2022-02-03 14:10:51 +0700
committerSerge Pavlov <sepavloff@gmail.com>2022-02-03 16:45:56 +0700
commitd2f132f0b7ebce919f5c4714e19449ee7869f3f7 (patch)
tree049f62eccf57968f12a3cb2918a83f841728f913 /llvm/lib/Analysis/ConstantFolding.cpp
parentbecb29aeb6a20362e77da0d24b7607437fd46d35 (diff)
downloadllvm-d2f132f0b7ebce919f5c4714e19449ee7869f3f7.zip
llvm-d2f132f0b7ebce919f5c4714e19449ee7869f3f7.tar.gz
llvm-d2f132f0b7ebce919f5c4714e19449ee7869f3f7.tar.bz2
[ConstantFolding] Fold constrained compare intrinsics
The change implements constant folding of ‘llvm.experimental.constrained.fcmp’ and ‘llvm.experimental.constrained.fcmps’ intrinsics. Differential Revision: https://reviews.llvm.org/D110322
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 7cf69f6..a21d3cec 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1527,6 +1527,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::experimental_constrained_trunc:
case Intrinsic::experimental_constrained_nearbyint:
case Intrinsic::experimental_constrained_rint:
+ case Intrinsic::experimental_constrained_fcmp:
+ case Intrinsic::experimental_constrained_fcmps:
return true;
default:
return false;
@@ -1798,12 +1800,12 @@ static bool mayFoldConstrained(ConstrainedFPIntrinsic *CI,
// If evaluation raised FP exception, the result can depend on rounding
// mode. If the latter is unknown, folding is not possible.
- if (!ORM || *ORM == RoundingMode::Dynamic)
+ if (ORM && *ORM == RoundingMode::Dynamic)
return false;
// If FP exceptions are ignored, fold the call, even if such exception is
// raised.
- if (!EB || *EB != fp::ExceptionBehavior::ebStrict)
+ if (EB && *EB != fp::ExceptionBehavior::ebStrict)
return true;
// Leave the calculation for runtime so that exception flags be correctly set
@@ -2301,6 +2303,25 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return nullptr;
}
+static Constant *evaluateCompare(const ConstrainedFPIntrinsic *Call) {
+ APFloat::opStatus St = APFloat::opOK;
+ auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
+ FCmpInst::Predicate Cond = FCmp->getPredicate();
+ const APFloat &Op1 = cast<ConstantFP>(FCmp->getOperand(0))->getValueAPF();
+ const APFloat &Op2 = cast<ConstantFP>(FCmp->getOperand(1))->getValueAPF();
+ if (FCmp->isSignaling()) {
+ if (Op1.isNaN() || Op2.isNaN())
+ St = APFloat::opInvalidOp;
+ } else {
+ if (Op1.isSignaling() || Op2.isSignaling())
+ St = APFloat::opInvalidOp;
+ }
+ bool Result = FCmpInst::compare(Op1, Op2, Cond);
+ if (mayFoldConstrained(const_cast<ConstrainedFPCmpIntrinsic *>(FCmp), St))
+ return ConstantInt::get(Call->getType(), Result);
+ return nullptr;
+}
+
static Constant *ConstantFoldScalarCall2(StringRef Name,
Intrinsic::ID IntrinsicID,
Type *Ty,
@@ -2329,8 +2350,6 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
}
if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
- if (!Ty->isFloatingPointTy())
- return nullptr;
const APFloat &Op1V = Op1->getValueAPF();
if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
@@ -2360,6 +2379,9 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
case Intrinsic::experimental_constrained_frem:
St = Res.mod(Op2V);
break;
+ case Intrinsic::experimental_constrained_fcmp:
+ case Intrinsic::experimental_constrained_fcmps:
+ return evaluateCompare(ConstrIntr);
}
if (mayFoldConstrained(const_cast<ConstrainedFPIntrinsic *>(ConstrIntr),
St))