Skip to content

Commit d2f132f

Browse files
committed
[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
1 parent becb29a commit d2f132f

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ class ConstrainedFPIntrinsic : public IntrinsicInst {
492492
class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
493493
public:
494494
FCmpInst::Predicate getPredicate() const;
495+
bool isSignaling() const {
496+
return getIntrinsicID() == Intrinsic::experimental_constrained_fcmps;
497+
}
495498

496499
// Methods for support type inquiry through isa, cast, and dyn_cast:
497500
static bool classof(const IntrinsicInst *I) {

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
15271527
case Intrinsic::experimental_constrained_trunc:
15281528
case Intrinsic::experimental_constrained_nearbyint:
15291529
case Intrinsic::experimental_constrained_rint:
1530+
case Intrinsic::experimental_constrained_fcmp:
1531+
case Intrinsic::experimental_constrained_fcmps:
15301532
return true;
15311533
default:
15321534
return false;
@@ -1798,12 +1800,12 @@ static bool mayFoldConstrained(ConstrainedFPIntrinsic *CI,
17981800

17991801
// If evaluation raised FP exception, the result can depend on rounding
18001802
// mode. If the latter is unknown, folding is not possible.
1801-
if (!ORM || *ORM == RoundingMode::Dynamic)
1803+
if (ORM && *ORM == RoundingMode::Dynamic)
18021804
return false;
18031805

18041806
// If FP exceptions are ignored, fold the call, even if such exception is
18051807
// raised.
1806-
if (!EB || *EB != fp::ExceptionBehavior::ebStrict)
1808+
if (EB && *EB != fp::ExceptionBehavior::ebStrict)
18071809
return true;
18081810

18091811
// Leave the calculation for runtime so that exception flags be correctly set
@@ -2301,6 +2303,25 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
23012303
return nullptr;
23022304
}
23032305

2306+
static Constant *evaluateCompare(const ConstrainedFPIntrinsic *Call) {
2307+
APFloat::opStatus St = APFloat::opOK;
2308+
auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
2309+
FCmpInst::Predicate Cond = FCmp->getPredicate();
2310+
const APFloat &Op1 = cast<ConstantFP>(FCmp->getOperand(0))->getValueAPF();
2311+
const APFloat &Op2 = cast<ConstantFP>(FCmp->getOperand(1))->getValueAPF();
2312+
if (FCmp->isSignaling()) {
2313+
if (Op1.isNaN() || Op2.isNaN())
2314+
St = APFloat::opInvalidOp;
2315+
} else {
2316+
if (Op1.isSignaling() || Op2.isSignaling())
2317+
St = APFloat::opInvalidOp;
2318+
}
2319+
bool Result = FCmpInst::compare(Op1, Op2, Cond);
2320+
if (mayFoldConstrained(const_cast<ConstrainedFPCmpIntrinsic *>(FCmp), St))
2321+
return ConstantInt::get(Call->getType(), Result);
2322+
return nullptr;
2323+
}
2324+
23042325
static Constant *ConstantFoldScalarCall2(StringRef Name,
23052326
Intrinsic::ID IntrinsicID,
23062327
Type *Ty,
@@ -2329,8 +2350,6 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
23292350
}
23302351

23312352
if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
2332-
if (!Ty->isFloatingPointTy())
2333-
return nullptr;
23342353
const APFloat &Op1V = Op1->getValueAPF();
23352354

23362355
if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
@@ -2360,6 +2379,9 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
23602379
case Intrinsic::experimental_constrained_frem:
23612380
St = Res.mod(Op2V);
23622381
break;
2382+
case Intrinsic::experimental_constrained_fcmp:
2383+
case Intrinsic::experimental_constrained_fcmps:
2384+
return evaluateCompare(ConstrIntr);
23632385
}
23642386
if (mayFoldConstrained(const_cast<ConstrainedFPIntrinsic *>(ConstrIntr),
23652387
St))

llvm/test/Transforms/InstSimplify/constfold-constrained.ll

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,7 @@ entry:
421421
define i1 @cmp_eq_01() #0 {
422422
; CHECK-LABEL: @cmp_eq_01(
423423
; CHECK-NEXT: entry:
424-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 1.000000e+00, double 2.000000e+00, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
425-
; CHECK-NEXT: ret i1 [[RESULT]]
424+
; CHECK-NEXT: ret i1 false
426425
;
427426
entry:
428427
%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:
432431
define i1 @cmp_eq_02() #0 {
433432
; CHECK-LABEL: @cmp_eq_02(
434433
; CHECK-NEXT: entry:
435-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 2.000000e+00, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
436-
; CHECK-NEXT: ret i1 [[RESULT]]
434+
; CHECK-NEXT: ret i1 true
437435
;
438436
entry:
439437
%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:
443441
define i1 @cmp_eq_03() #0 {
444442
; CHECK-LABEL: @cmp_eq_03(
445443
; CHECK-NEXT: entry:
446-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 0x7FF8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
447-
; CHECK-NEXT: ret i1 [[RESULT]]
444+
; CHECK-NEXT: ret i1 false
448445
;
449446
entry:
450447
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.0, double 0x7ff8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -454,8 +451,7 @@ entry:
454451
define i1 @cmp_eq_04() #0 {
455452
; CHECK-LABEL: @cmp_eq_04(
456453
; CHECK-NEXT: entry:
457-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.000000e+00, double 0x7FF4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
458-
; CHECK-NEXT: ret i1 [[RESULT]]
454+
; CHECK-NEXT: ret i1 false
459455
;
460456
entry:
461457
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 2.0, double 0x7ff4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -465,8 +461,7 @@ entry:
465461
define i1 @cmp_eq_05() #0 {
466462
; CHECK-LABEL: @cmp_eq_05(
467463
; CHECK-NEXT: entry:
468-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.000000e+00, double 0x7FF8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
469-
; CHECK-NEXT: ret i1 [[RESULT]]
464+
; CHECK-NEXT: ret i1 false
470465
;
471466
entry:
472467
%result = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.0, double 0x7ff8000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #0
@@ -476,8 +471,7 @@ entry:
476471
define i1 @cmp_eq_06() #0 {
477472
; CHECK-LABEL: @cmp_eq_06(
478473
; CHECK-NEXT: entry:
479-
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 2.000000e+00, double 0x7FF4000000000000, metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
480-
; CHECK-NEXT: ret i1 [[RESULT]]
474+
; CHECK-NEXT: ret i1 false
481475
;
482476
entry:
483477
%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 {
512506
; CHECK-LABEL: @cmp_eq_nan_03(
513507
; CHECK-NEXT: entry:
514508
; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
515-
; CHECK-NEXT: ret i1 [[RESULT]]
509+
; CHECK-NEXT: ret i1 false
516510
;
517511
entry:
518512
%result = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7ff8000000000000, double 1.0, metadata !"oeq", metadata !"fpexcept.strict") #0

0 commit comments

Comments
 (0)