@@ -381,6 +381,13 @@ static SILValue constantFoldIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID,
381381 return nullptr ;
382382}
383383
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+
384391static SILValue constantFoldCompareFloat (BuiltinInst *BI, BuiltinValueKind ID) {
385392 static auto hasIEEEFloatNanBitRepr = [](const APInt val) -> bool {
386393 auto bitWidth = val.getBitWidth ();
@@ -640,17 +647,11 @@ static SILValue constantFoldCompareFloat(BuiltinInst *BI, BuiltinValueKind ID) {
640647 m_BuiltinInst (BuiltinValueKind::FCMP_ULE,
641648 m_SILValue (Other), m_BitCast (m_IntegerLiteralInst (builtinArg)))))) {
642649 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 ));
654655 }
655656 }
656657
@@ -682,17 +683,11 @@ static SILValue constantFoldCompareFloat(BuiltinInst *BI, BuiltinValueKind ID) {
682683 m_BuiltinInst (BuiltinValueKind::FCMP_ULE,
683684 m_BitCast (m_IntegerLiteralInst (builtinArg)), m_SILValue (Other))))) {
684685 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 ));
696691 }
697692 }
698693
0 commit comments