[llvm] d2f132f - [ConstantFolding] Fold constrained compare intrinsics
Serge Pavlov via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 3 01:47:12 PST 2022
Author: Serge Pavlov
Date: 2022-02-03T16:45:56+07:00
New Revision: d2f132f0b7ebce919f5c4714e19449ee7869f3f7
URL: https://github.com/llvm/llvm-project/commit/d2f132f0b7ebce919f5c4714e19449ee7869f3f7
DIFF: https://github.com/llvm/llvm-project/commit/d2f132f0b7ebce919f5c4714e19449ee7869f3f7.diff
LOG: [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
Added:
Modified:
llvm/include/llvm/IR/IntrinsicInst.h
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstSimplify/constfold-constrained.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index 01dada25a2854..cd6299431e634 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -492,6 +492,9 @@ class ConstrainedFPIntrinsic : public IntrinsicInst {
class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
public:
FCmpInst::Predicate getPredicate() const;
+ bool isSignaling() const {
+ return getIntrinsicID() == Intrinsic::experimental_constrained_fcmps;
+ }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const IntrinsicInst *I) {
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 7cf69f613c669..a21d3cec37e48 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))
diff --git a/llvm/test/Transforms/InstSimplify/constfold-constrained.ll b/llvm/test/Transforms/InstSimplify/constfold-constrained.ll
index 5b8d615a67700..ff850e5949bda 100644
--- a/llvm/test/Transforms/InstSimplify/constfold-constrained.ll
+++ b/llvm/test/Transforms/InstSimplify/constfold-constrained.ll
@@ -421,8 +421,7 @@ entry:
define i1 @cmp_eq_01() #0 {
; CHECK-LABEL: @cmp_eq_01(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 1.000000e+00, double 2.000000e+00, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 1.0, double 2.0, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -432,8 +431,7 @@ entry:
define i1 @cmp_eq_02() #0 {
; CHECK-LABEL: @cmp_eq_02(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 2.000000e+00, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 true
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.0, double 2.0, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -443,8 +441,7 @@ entry:
define i1 @cmp_eq_03() #0 {
; CHECK-LABEL: @cmp_eq_03(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 0x7FF8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.0, double 0x7ff8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -454,8 +451,7 @@ entry:
define i1 @cmp_eq_04() #0 {
; CHECK-LABEL: @cmp_eq_04(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 0x7FF4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.0, double 0x7ff4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -465,8 +461,7 @@ entry:
define i1 @cmp_eq_05() #0 {
; CHECK-LABEL: @cmp_eq_05(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.000000e+00, double 0x7FF8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.0, double 0x7ff8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -476,8 +471,7 @@ entry:
define i1 @cmp_eq_06() #0 {
; CHECK-LABEL: @cmp_eq_06(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.000000e+00, double 0x7FF4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.0, double 0x7ff4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -512,7 +506,7 @@ define i1 @cmp_eq_nan_03() #0 {
; CHECK-LABEL: @cmp_eq_nan_03(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
;
entry:
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7ff8000000000000, double 1.0, metadata !"oeq", metadata !"fpexcept.strict") #0
More information about the llvm-commits
mailing list