@@ -381,6 +381,13 @@ static SILValue constantFoldIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID,
381
381
return nullptr ;
382
382
}
383
383
384
+ static bool isFiniteFloatLiteral (SILValue v) {
385
+ if (auto *lit = dyn_cast<FloatLiteralInst>(v)) {
386
+ return lit->getValue ().isFinite ();
387
+ }
388
+ return false ;
389
+ }
390
+
384
391
static SILValue constantFoldCompareFloat (BuiltinInst *BI, BuiltinValueKind ID) {
385
392
static auto hasIEEEFloatNanBitRepr = [](const APInt val) -> bool {
386
393
auto bitWidth = val.getBitWidth ();
@@ -640,17 +647,11 @@ static SILValue constantFoldCompareFloat(BuiltinInst *BI, BuiltinValueKind ID) {
640
647
m_BuiltinInst (BuiltinValueKind::FCMP_ULE,
641
648
m_SILValue (Other), m_BitCast (m_IntegerLiteralInst (builtinArg)))))) {
642
649
APInt val = builtinArg->getValue ();
643
- if (hasIEEEFloatPosInfBitRepr (val)) {
644
- // One of the operands is infinity, but unless the other operand is not
645
- // fully visible we cannot definitively say what it is. It can be anything,
646
- // including NaN and infinity itself. Therefore, we cannot fold the comparison
647
- // just yet.
648
- if (isa<StructExtractInst>(Other) || isa<TupleExtractInst>(Other)) {
649
- return nullptr ;
650
- } else {
651
- SILBuilderWithScope B (BI);
652
- return B.createIntegerLiteral (BI->getLoc (), BI->getType (), APInt (1 , 1 ));
653
- }
650
+ if (hasIEEEFloatPosInfBitRepr (val) &&
651
+ // Only if `Other` is a literal we can be sure that it's not Inf or NaN.
652
+ isFiniteFloatLiteral (Other)) {
653
+ SILBuilderWithScope B (BI);
654
+ return B.createIntegerLiteral (BI->getLoc (), BI->getType (), APInt (1 , 1 ));
654
655
}
655
656
}
656
657
@@ -682,17 +683,11 @@ static SILValue constantFoldCompareFloat(BuiltinInst *BI, BuiltinValueKind ID) {
682
683
m_BuiltinInst (BuiltinValueKind::FCMP_ULE,
683
684
m_BitCast (m_IntegerLiteralInst (builtinArg)), m_SILValue (Other))))) {
684
685
APInt val = builtinArg->getValue ();
685
- if (hasIEEEFloatPosInfBitRepr (val)) {
686
- // One of the operands is infinity, but unless the other operand is not
687
- // fully visible we cannot definitively say what it is. It can be anything,
688
- // including NaN and infinity itself. Therefore, we cannot fold the comparison
689
- // just yet.
690
- if (isa<StructExtractInst>(Other) || isa<TupleExtractInst>(Other)) {
691
- return nullptr ;
692
- } else {
693
- SILBuilderWithScope B (BI);
694
- return B.createIntegerLiteral (BI->getLoc (), BI->getType (), APInt (1 , 0 ));
695
- }
686
+ if (hasIEEEFloatPosInfBitRepr (val) &&
687
+ // Only if `Other` is a literal we can be sure that it's not Inf or NaN.
688
+ isFiniteFloatLiteral (Other)) {
689
+ SILBuilderWithScope B (BI);
690
+ return B.createIntegerLiteral (BI->getLoc (), BI->getType (), APInt (1 , 0 ));
696
691
}
697
692
}
698
693
0 commit comments