Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -980,8 +980,7 @@ return replaceInstUsesWith(II, FCmp); } - KnownFPClass Known = computeKnownFPClass( - Src0, DL, Mask, 0, &getTargetLibraryInfo(), &AC, &II, &DT); + KnownFPClass Known = computeKnownFPClass(Src0, Mask, &II); // Clear test bits we know must be false from the source value. // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other Index: llvm/lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -198,6 +198,29 @@ LoadInst *combineLoadToNewType(LoadInst &LI, Type *NewTy, const Twine &Suffix = ""); + KnownFPClass computeKnownFPClass(Value *Val, + FPClassTest Interested = fcAllFlags, + FastMathFlags FMF = FastMathFlags(), + const Instruction *CtxI = nullptr, + unsigned Depth = 0) const { + // TODO: Use FMF when computeKnownFPClass FMF wrapper is pushed. + return llvm::computeKnownFPClass(Val, DL, Interested, Depth, &TLI, &AC, + CtxI, &DT); + } + + KnownFPClass computeKnownFPClass(Value *Val, + FPClassTest Interested = fcAllFlags, + const Instruction *CtxI = nullptr, + unsigned Depth = 0) const { + return llvm::computeKnownFPClass(Val, DL, Interested, Depth, &TLI, &AC, + CtxI, &DT); + } + + /// Check if fmul \p MulVal, +0.0 will yield +0.0 (or signed zero is + /// ignorable). + bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, + const Instruction *CtxI) const; + private: bool annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI); bool isDesirableIntType(unsigned BitWidth) const; Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3305,6 +3305,39 @@ Masked); } +bool InstCombinerImpl::fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, + const Instruction *CtxI) const { + FPClassTest Interested = fcNegative; + if (!FMF.noNaNs()) + Interested |= fcNan; + if (!FMF.noInfs()) + Interested |= fcInf; + + // TODO: Use flag wrapper when pushed. + KnownFPClass Known = computeKnownFPClass(MulVal, Interested, FMF, CtxI); + + return (FMF.noNaNs() || Known.isKnownNeverNaN()) && + (FMF.noInfs() || Known.isKnownNeverInfinity()) && + (FMF.noSignedZeros() || Known.signBitIsZeroOrNaN()); +} + +static bool matchFMulByZeroIfResultEqZero(InstCombinerImpl &IC, Value *Cmp0, + Value *Cmp1, Value *TrueVal, + Value *FalseVal, Instruction &CtxI, + bool SelectIsNSZ) { + Value *MulRHS; + if (match(Cmp1, m_PosZeroFP()) && + match(TrueVal, m_c_FMul(m_Specific(Cmp0), m_Value(MulRHS)))) { + FastMathFlags FMF = cast(TrueVal)->getFastMathFlags(); + // nsz must be on the select, it must be ignored on the multiply. We + // need nnan and ninf on the multiply for the other value. + FMF.setNoSignedZeros(SelectIsNSZ); + return IC.fmulByZeroIsZero(MulRHS, FMF, &CtxI); + } + + return false; +} + Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { Value *CondVal = SI.getCondition(); Value *TrueVal = SI.getTrueValue(); @@ -3395,7 +3428,10 @@ } } + auto *SIFPOp = dyn_cast(&SI); + if (auto *FCmp = dyn_cast(CondVal)) { + FCmpInst::Predicate Pred = FCmp->getPredicate(); Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1); // Are we selecting a value based on a comparison of the two values? if ((Cmp0 == TrueVal && Cmp1 == FalseVal) || @@ -3405,7 +3441,7 @@ // // e.g. // (X ugt Y) ? X : Y -> (X ole Y) ? Y : X - if (FCmp->hasOneUse() && FCmpInst::isUnordered(FCmp->getPredicate())) { + if (FCmp->hasOneUse() && FCmpInst::isUnordered(Pred)) { FCmpInst::Predicate InvPred = FCmp->getInversePredicate(); IRBuilder<>::FastMathFlagGuard FMFG(Builder); // FIXME: The FMF should propagate from the select, not the fcmp. @@ -3416,14 +3452,47 @@ return replaceInstUsesWith(SI, NewSel); } } + + if (SIFPOp) { + // Fold out scale-if-equals-zero pattern. + // + // This pattern appears in code with denormal range checks after it's + // assumed denormals are treated as zero. This drops a canonicalization. + + // TODO: Could relax the signed zero logic. We just need to know the sign + // of the result matches (fmul x, y has the same sign as x). + // + // TODO: Handle always-canonicalizing variant that selects some value or 1 + // scaling factor in the fmul visitor. + + // TODO: Handle ldexp too + + Value *MatchCmp0 = nullptr; + Value *MatchCmp1 = nullptr; + + // (select (fcmp [ou]eq x, 0.0), (fmul x, K), x => x + // (select (fcmp [ou]ne x, 0.0), x, (fmul x, K) => x + if (Pred == CmpInst::FCMP_OEQ || Pred == CmpInst::FCMP_UEQ) { + MatchCmp0 = FalseVal; + MatchCmp1 = TrueVal; + } else if (Pred == CmpInst::FCMP_ONE || Pred == CmpInst::FCMP_UNE) { + MatchCmp0 = TrueVal; + MatchCmp1 = FalseVal; + } + + if (Cmp0 == MatchCmp0 && + matchFMulByZeroIfResultEqZero(*this, Cmp0, Cmp1, MatchCmp1, MatchCmp0, + SI, SIFPOp->hasNoSignedZeros())) + return replaceInstUsesWith(SI, Cmp0); + } } - if (isa(SI)) { + if (SIFPOp) { // TODO: Try to forward-propagate FMF from select arms to the select. // Canonicalize select of FP values where NaN and -0.0 are not valid as // minnum/maxnum intrinsics. - if (SI.hasNoNaNs() && SI.hasNoSignedZeros()) { + if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) { Value *X, *Y; if (match(&SI, m_OrdFMax(m_Value(X), m_Value(Y)))) return replaceInstUsesWith( Index: llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll =================================================================== --- llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll +++ llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll @@ -14,10 +14,7 @@ define i32 @fcmp_zero_select_is_not_fp(float %x) { ; CHECK-LABEL: @fcmp_zero_select_is_not_fp( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL_V:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = bitcast float [[SCALED_IF_DENORMAL_V]] to i32 +; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = bitcast float [[X:%.*]] to i32 ; CHECK-NEXT: ret i32 [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 @@ -42,10 +39,7 @@ ; Real case define float @fmul_by_32_if_0_oeq_zero_f32(float %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_f32( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -108,10 +102,7 @@ ; Real case, vector splat define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_splat(<2 x float> %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_v2f32_splat( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul <2 x float> [[X]], -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> [[SCALED_X]], <2 x float> [[X]] -; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer %scaled.x = fmul <2 x float> %x, @@ -121,10 +112,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_nonsplat(<2 x float> %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_v2f32_nonsplat( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul <2 x float> [[X]], -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> [[SCALED_X]], <2 x float> [[X]] -; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer %scaled.x = fmul <2 x float> %x, @@ -134,10 +122,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_eq_mixed_zero_vector(<2 x float> %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_v2f32_eq_mixed_zero_vector( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul <2 x float> [[X]], -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> [[SCALED_X]], <2 x float> [[X]] -; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %x.is.zero = fcmp oeq <2 x float> %x, %scaled.x = fmul <2 x float> %x, @@ -147,10 +132,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_eq_zero_vector_undef(<2 x float> %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_v2f32_eq_zero_vector_undef( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul <2 x float> [[X]], -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> [[SCALED_X]], <2 x float> [[X]] -; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %x.is.zero = fcmp oeq <2 x float> %x, %scaled.x = fmul <2 x float> %x, @@ -212,10 +194,7 @@ define float @fmul_by_32_if_0_ueq_zero_f32(float %x) { ; CHECK-LABEL: @fmul_by_32_if_0_ueq_zero_f32( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp ueq float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -225,10 +204,7 @@ define float @fmul_by_32_if_0_oeq_negzero_f32(float %x) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_negzero_f32( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, -0.0 %scaled.x = fmul float %x, 32.0 @@ -239,10 +215,8 @@ define float @fmul_by_32_if_0_oeq_zero_f32_multiple_use_cmp(float %x, ptr %ptr) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_f32_multiple_use_cmp( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 ; CHECK-NEXT: store i1 [[X_IS_ZERO]], ptr [[PTR:%.*]], align 1 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -253,11 +227,9 @@ define float @fmul_by_32_if_0_oeq_zero_f32_multiple_use_fmul(float %x, ptr %ptr) { ; CHECK-LABEL: @fmul_by_32_if_0_oeq_zero_f32_multiple_use_fmul( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 +; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X:%.*]], 3.200000e+01 ; CHECK-NEXT: store float [[SCALED_X]], ptr [[PTR:%.*]], align 4 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -268,10 +240,7 @@ define float @fmul_by_0_if_0_oeq_zero_f32(float %x) { ; CHECK-LABEL: @fmul_by_0_if_0_oeq_zero_f32( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, 0.0 @@ -282,10 +251,7 @@ ; Inverse of the real case define float @x_if_one_zero_else_mul_by_32(float %x) { ; CHECK-LABEL: @x_if_one_zero_else_mul_by_32( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[X]], float [[SCALED_X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp one float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -295,10 +261,7 @@ define float @x_if_one_negzero_else_mul_by_32(float %x) { ; CHECK-LABEL: @x_if_one_negzero_else_mul_by_32( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[X]], float [[SCALED_X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp one float %x, -0.0 %scaled.x = fmul float %x, 32.0 @@ -308,10 +271,7 @@ define float @x_if_une_zero_else_mul_by_32(float %x) { ; CHECK-LABEL: @x_if_une_zero_else_mul_by_32( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[X]], float [[SCALED_X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp une float %x, 0.0 %scaled.x = fmul float %x, 32.0 @@ -321,10 +281,7 @@ define float @x_if_une_negzero_else_mul_by_32(float %x) { ; CHECK-LABEL: @x_if_une_negzero_else_mul_by_32( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_NOT_ZERO]], float [[X]], float [[SCALED_X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp une float %x, -0.0 %scaled.x = fmul float %x, 32.0 @@ -360,10 +317,7 @@ define float @fmul_by_neg32_if_0_oeq_zero_f32_select_nsz(float %x) { ; CHECK-LABEL: @fmul_by_neg32_if_0_oeq_zero_f32_select_nsz( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], -3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select nsz i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, -32.0 @@ -373,10 +327,7 @@ define float @fmul_by_neg32_if_0_one_zero_f32_select_nsz(float %x) { ; CHECK-LABEL: @fmul_by_neg32_if_0_one_zero_f32_select_nsz( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = fmul float [[X]], -3.200000e+01 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select nsz i1 [[X_IS_NOT_ZERO]], float [[X]], float [[SCALED_X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp one float %x, 0.0 %scaled.x = fmul float %x, -32.0 @@ -503,11 +454,7 @@ define float @fmul_by_fabs_nnan_ninf_var_if_0_oeq_zero_f32(float %x, float %y) { ; CHECK-LABEL: @fmul_by_fabs_nnan_ninf_var_if_0_oeq_zero_f32( -; CHECK-NEXT: [[Y_FABS:%.*]] = call nnan ninf float @llvm.fabs.f32(float [[Y:%.*]]) -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y_FABS]], float 1.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %y.fabs = call nnan ninf float @llvm.fabs.f32(float %y) %x.is.zero = fcmp oeq float %x, 0.0 @@ -589,10 +536,7 @@ ; nsz can come from only the select define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select nsz i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf float %x, %y @@ -603,10 +547,7 @@ ; nsz can come from only the select define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz_inverted(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz_inverted( -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select nsz i1 [[X_IS_NOT_ZERO]], float 1.000000e+00, float [[Y:%.*]] -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.not.zero = fcmp one float %x, 0.0 %scaled.x = fmul nnan ninf float %x, %y @@ -669,10 +610,7 @@ define float @fmul_by_var_if_0_oeq_zero_f32_known_never_nan_inf_select_nsz(float %x, float nofpclass(nan inf) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_known_never_nan_inf_select_nsz( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select nsz i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y @@ -709,10 +647,7 @@ define float @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_neg(float %x, float nofpclass(nan inf nzero nsub nnorm) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_neg( -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y @@ -726,10 +661,7 @@ ; CHECK-NEXT: [[FABS_Y:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]]) ; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt float [[FABS_Y]], 0x7FF0000000000000 ; CHECK-NEXT: call void @llvm.assume(i1 [[IS_FINITE]]) -; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select nsz i1 [[X_IS_ZERO]], float [[Y]], float 1.000000e+00 -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %fabs.y = call float @llvm.fabs.f32(float %y) %is.finite = fcmp olt float %fabs.y, 0x7FF0000000000000 @@ -746,10 +678,7 @@ ; CHECK-NEXT: [[FABS_Y:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]]) ; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt float [[FABS_Y]], 0x7FF0000000000000 ; CHECK-NEXT: call void @llvm.assume(i1 [[IS_FINITE]]) -; CHECK-NEXT: [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select nsz i1 [[X_IS_NOT_ZERO]], float 1.000000e+00, float [[Y]] -; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] -; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] +; CHECK-NEXT: ret float [[X:%.*]] ; %fabs.y = call float @llvm.fabs.f32(float %y) %is.finite = fcmp olt float %fabs.y, 0x7FF0000000000000