https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/175974
>From 615f5e8e1be92ca09138e7ea18ac1a3f613f909d Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Wed, 14 Jan 2026 14:47:11 +0100 Subject: [PATCH] InstCombine: Handle multiple uses for min/max in SimplifyDemandedFPClass --- .../InstCombineSimplifyDemanded.cpp | 218 ++++++++++-------- .../simplify-demanded-fpclass-maximum.ll | 8 +- .../simplify-demanded-fpclass-maximumnum.ll | 8 +- .../simplify-demanded-fpclass-minimum.ll | 8 +- .../simplify-demanded-fpclass-minimumnum.ll | 8 +- 5 files changed, 143 insertions(+), 107 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 6275d5624197e..358fac1ec07d7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -2033,6 +2033,101 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask, } } +static Value * +simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID, + const CallInst *CI, FPClassTest DemandedMask, + KnownFPClass KnownLHS, KnownFPClass KnownRHS, + const Function &F, bool NSZ) { + const bool PropagateNaN = + IID == Intrinsic::maximum || IID == Intrinsic::minimum; + + /// Propagate nnan-ness to simplify edge case checks. + if (PropagateNaN && (DemandedMask & fcNan) == fcNone) { + KnownLHS.knownNot(fcNan); + KnownRHS.knownNot(fcNan); + } + + bool OrderedZeroSign = !NSZ; + + KnownFPClass::MinMaxKind OpKind; + switch (IID) { + case Intrinsic::maximum: { + OpKind = KnownFPClass::MinMaxKind::maximum; + + // If one operand is known greater than the other, it must be that + // operand unless the other is a nan. + if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownRHS.isKnownNever(fcNan)) + return CI->getArgOperand(0); + + if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownLHS.isKnownNever(fcNan)) + return CI->getArgOperand(1); + + break; + } + case Intrinsic::minimum: { + OpKind = KnownFPClass::MinMaxKind::minimum; + + // If one operand is known less than the other, it must be that operand + // unless the other is a nan. + if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownRHS.isKnownNever(fcNan)) + return CI->getArgOperand(0); + + if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownLHS.isKnownNever(fcNan)) + return CI->getArgOperand(1); + + break; + } + case Intrinsic::maximumnum: { + OpKind = KnownFPClass::MinMaxKind::maximumnum; + + if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownLHS.isKnownNever(fcNan)) + return CI->getArgOperand(0); + + if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownRHS.isKnownNever(fcNan)) + return CI->getArgOperand(1); + + break; + } + case Intrinsic::minimumnum: { + OpKind = KnownFPClass::MinMaxKind::minimumnum; + + if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownLHS.isKnownNever(fcNan)) + return CI->getArgOperand(0); + + if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, + KnownRHS.KnownFPClasses, OrderedZeroSign) && + KnownRHS.isKnownNever(fcNan)) + return CI->getArgOperand(1); + + break; + } + default: + llvm_unreachable("not a min/max intrinsic"); + } + + Type *EltTy = CI->getType()->getScalarType(); + DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics()); + Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, OpKind, Mode); + + FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses; + return getFPClassConstant(CI->getType(), ValidResults, + /*IsCanonicalizing=*/true); +} + /// Try to set an inferred no-nans or no-infs in \p FMF. \p /// ValidResults is a mask of known valid results for the operator /// (already computed from the result, and the known operand inputs, @@ -2447,101 +2542,16 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I, SimplifyDemandedFPClass(CI, 0, SrcDemandedMask, KnownLHS, Depth + 1)) return I; - /// Propagate nnan-ness to simplify edge case checks. - if (PropagateNaN && (DemandedMask & fcNan) == fcNone) { - KnownLHS.knownNot(fcNan); - KnownRHS.knownNot(fcNan); - } - - bool OrderedZeroSign = !FMF.noSignedZeros(); - - KnownFPClass::MinMaxKind OpKind; - switch (IID) { - case Intrinsic::maximum: { - OpKind = KnownFPClass::MinMaxKind::maximum; - - // If one operand is known greater than the other, it must be that - // operand unless the other is a nan. - if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, OrderedZeroSign) && - KnownRHS.isKnownNever(fcNan)) - return CI->getArgOperand(0); - - if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, - OrderedZeroSign) && - KnownLHS.isKnownNever(fcNan)) - return CI->getArgOperand(1); - - break; - } - case Intrinsic::minimum: { - OpKind = KnownFPClass::MinMaxKind::minimum; - - // If one operand is known less than the other, it must be that operand - // unless the other is a nan. - if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, - OrderedZeroSign) && - KnownRHS.isKnownNever(fcNan)) - return CI->getArgOperand(0); - - if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, OrderedZeroSign) && - KnownLHS.isKnownNever(fcNan)) - return CI->getArgOperand(1); - - break; - } - case Intrinsic::maximumnum: { - OpKind = KnownFPClass::MinMaxKind::maximumnum; - - if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, OrderedZeroSign) && - KnownLHS.isKnownNever(fcNan)) - return CI->getArgOperand(0); - - if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, - OrderedZeroSign) && - KnownRHS.isKnownNever(fcNan)) - return CI->getArgOperand(1); - - break; - } - case Intrinsic::minimumnum: { - OpKind = KnownFPClass::MinMaxKind::minimumnum; - - if (cannotOrderStrictlyGreater(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, - OrderedZeroSign) && - KnownLHS.isKnownNever(fcNan)) - return CI->getArgOperand(0); - - if (cannotOrderStrictlyLess(KnownLHS.KnownFPClasses, - KnownRHS.KnownFPClasses, OrderedZeroSign) && - KnownRHS.isKnownNever(fcNan)) - return CI->getArgOperand(1); - - break; - } - default: - llvm_unreachable("not a min/max intrinsic"); - } - - Type *EltTy = VTy->getScalarType(); - DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics()); - Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, OpKind, Mode); - - FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses; - - if (Constant *SingleVal = - getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true)) - return SingleVal; + Value *Simplified = + simplifyDemandedFPClassMinMax(Known, IID, CI, DemandedMask, KnownLHS, + KnownRHS, F, FMF.noSignedZeros()); + if (Simplified) + return Simplified; auto *FPOp = cast<FPMathOperator>(CI); bool ChangedFlags = false; + FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses; // TODO: Add NSZ flag if we know the result will not be sensitive on the // sign of 0. @@ -2950,6 +2960,32 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass( Known = KnownLHS.intersectWith(KnownRHS); break; } + case Instruction::Call: { + const CallInst *CI = cast<CallInst>(I); + const Intrinsic::ID IID = CI->getIntrinsicID(); + switch (IID) { + case Intrinsic::maximum: + case Intrinsic::minimum: + case Intrinsic::maximumnum: + case Intrinsic::minimumnum: { + KnownFPClass KnownRHS = computeKnownFPClass( + CI->getArgOperand(1), DemandedMask, CxtI, Depth + 1); + if (KnownRHS.isUnknown()) + return nullptr; + + KnownFPClass KnownLHS = computeKnownFPClass( + CI->getArgOperand(0), DemandedMask, CxtI, Depth + 1); + + return simplifyDemandedFPClassMinMax( + Known, IID, CI, DemandedMask, KnownLHS, KnownRHS, F, + cast<FPMathOperator>(CI)->hasNoSignedZeros()); + } + default: + break; + } + + [[fallthrough]]; + } default: Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1); break; diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll index 4792e5198f96f..a06dd0e398380 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll @@ -2071,7 +2071,7 @@ define nofpclass(snan) float @simplify_multiple_use_maximum(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maximum.f32(float [[POSITIVE]], float [[NEGATIVE]]) ; CHECK-NEXT: store float [[MAX]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MAX]] +; CHECK-NEXT: ret float [[POSITIVE]] ; %positive = call float @returns_positive() %negative = call float @returns_negative() @@ -2087,7 +2087,7 @@ define nofpclass(snan) float @simplify_multiple_use_maximum_commute(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maximum.f32(float [[NEGATIVE]], float [[POSITIVE]]) ; CHECK-NEXT: store float [[MAX]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MAX]] +; CHECK-NEXT: ret float [[POSITIVE]] ; %positive = call float @returns_positive() %negative = call float @returns_negative() @@ -2103,7 +2103,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__mul ; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.maximum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]] ; %must.be.negative.or.zero = call float @returns_negative_or_zero() %must.be.positive.or.zero = call float @returns_positive_or_zero() @@ -2119,7 +2119,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__mul ; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.maximum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]] ; %must.be.positive.or.zero = call float @returns_positive_or_zero() %must.be.negative.or.zero = call float @returns_negative_or_zero() diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll index b9e0892a10ab3..76782bd2b5953 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll @@ -2076,7 +2076,7 @@ define nofpclass(snan) float @simplify_multiple_use_maximumnum(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan() ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maximumnum.f32(float [[POSITIVE]], float [[NEGATIVE_OR_NAN]]) ; CHECK-NEXT: store float [[MAX]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MAX]] +; CHECK-NEXT: ret float [[POSITIVE]] ; %positive = call float @returns_positive() %negative.or.nan = call float @returns_negative_or_nan() @@ -2092,7 +2092,7 @@ define nofpclass(snan) float @simplify_multiple_use_maximumnum_commute(ptr %ptr) ; CHECK-NEXT: [[NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan() ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maximumnum.f32(float [[NEGATIVE_OR_NAN]], float [[POSITIVE]]) ; CHECK-NEXT: store float [[MAX]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MAX]] +; CHECK-NEXT: ret float [[POSITIVE]] ; %positive = call float @returns_positive() %negative.or.nan = call float @returns_negative_or_nan() @@ -2108,7 +2108,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__mul ; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.maximumnum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]] ; %must.be.negative.or.zero = call float @returns_negative_or_zero() %must.be.positive.or.zero = call float @returns_positive_or_zero() @@ -2124,7 +2124,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__mul ; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.maximumnum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]] ; %must.be.negative.or.zero = call float @returns_negative_or_zero() %must.be.positive.or.zero = call float @returns_positive_or_zero() diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll index 91954deb5e1c7..d48ce25c94c50 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll @@ -2059,7 +2059,7 @@ define nofpclass(snan) float @simplify_multiple_use_minimum(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimum.f32(float [[POSITIVE]], float [[NEGATIVE]]) ; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MIN]] +; CHECK-NEXT: ret float [[NEGATIVE]] ; %positive = call float @returns_positive() %negative = call float @returns_negative() @@ -2075,7 +2075,7 @@ define nofpclass(snan) float @simplify_multiple_use_minimum_commute(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimum.f32(float [[NEGATIVE]], float [[POSITIVE]]) ; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MIN]] +; CHECK-NEXT: ret float [[NEGATIVE]] ; %positive = call float @returns_positive() %negative = call float @returns_negative() @@ -2091,7 +2091,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__mul ; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE_OR_ZERO]] ; %must.be.negative.or.zero = call float @returns_negative_or_zero() %must.be.positive.or.zero = call float @returns_positive_or_zero() @@ -2107,7 +2107,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__mul ; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE_OR_ZERO]] ; %must.be.positive.or.zero = call float @returns_positive_or_zero() %must.be.negative.or.zero = call float @returns_negative_or_zero() diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll index c0b73029b2a0a..65a04cacb0166 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll @@ -2067,7 +2067,7 @@ define nofpclass(snan) float @simplify_multiple_use_minimumnum(ptr %ptr) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimumnum.f32(float [[POSITIVE_OR_NAN]], float [[NEGATIVE]]) ; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MIN]] +; CHECK-NEXT: ret float [[NEGATIVE]] ; %positive.or.nan = call float @returns_positive_or_nan() %negative = call float @returns_negative() @@ -2083,7 +2083,7 @@ define nofpclass(snan) float @simplify_multiple_use_minimumnum_commute(ptr %ptr) ; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimumnum.f32(float [[NEGATIVE]], float [[POSITIVE_OR_NAN]]) ; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[MIN]] +; CHECK-NEXT: ret float [[NEGATIVE]] ; %positive.or.nan = call float @returns_positive_or_nan() %negative = call float @returns_negative() @@ -2099,7 +2099,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__mul ; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE_OR_ZERO]] ; %must.be.negative.or.zero = call float @returns_negative_or_zero() %must.be.positive.or.zero = call float @returns_positive_or_zero() @@ -2115,7 +2115,7 @@ define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__mul ; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero() ; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]]) ; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4 -; CHECK-NEXT: ret float [[RESULT]] +; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE_OR_ZERO]] ; %must.be.positive.or.zero = call float @returns_positive_or_zero() %must.be.negative.or.zero = call float @returns_negative_or_zero() _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
