diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2022-02-03 14:10:51 +0700 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2022-02-03 16:45:56 +0700 |
commit | d2f132f0b7ebce919f5c4714e19449ee7869f3f7 (patch) | |
tree | 049f62eccf57968f12a3cb2918a83f841728f913 /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | becb29aeb6a20362e77da0d24b7607437fd46d35 (diff) | |
download | llvm-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.cpp | 30 |
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)) |