[llvm] 5ae881f - InstCombine: Fold out scale-if-denormal pattern
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 1 04:47:17 PDT 2023
Author: Matt Arsenault
Date: 2023-09-01T07:47:12-04:00
New Revision: 5ae881ff0ab3a38121f240c9e73427367284e802
URL: https://github.com/llvm/llvm-project/commit/5ae881ff0ab3a38121f240c9e73427367284e802
DIFF: https://github.com/llvm/llvm-project/commit/5ae881ff0ab3a38121f240c9e73427367284e802.diff
LOG: InstCombine: Fold out scale-if-denormal pattern
Fold select (fcmp oeq x, 0), (fmul x, y), x => x
This cleans up a pattern left behind by denormal range checks under
denormals are zero.
The pattern starts out as something like:
x = x < smallest_normal ? x * K : x;
The comparison folds to an == 0 when the denormal mode treats input
denormals as zero. This makes library denormal checks free after
linked into DAZ enabled code.
alive2 is mostly happy with this, but there are some issues. First,
there are many reported failures in some of the negative tests that
happen to trigger some preexisting canonicalize introducing
combine. Second, alive2 is incorrectly asserting that denormals must
be flushed with the DAZ modes. It's allowed to drop a canonicalize.
https://reviews.llvm.org/D157030
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 5102c7fdcc9951..4be28aaee8746b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -996,8 +996,7 @@ Instruction *InstCombinerImpl::foldIntrinsicIsFPClass(IntrinsicInst &II) {
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
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 7e9b916783a0e7..8faf440d0a235a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -198,6 +198,27 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
LoadInst *combineLoadToNewType(LoadInst &LI, Type *NewTy,
const Twine &Suffix = "");
+ KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF,
+ FPClassTest Interested = fcAllFlags,
+ const Instruction *CtxI = nullptr,
+ unsigned Depth = 0) const {
+ return llvm::computeKnownFPClass(Val, FMF, 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;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 4fa31ed7518995..ee248d06373738 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3318,6 +3318,31 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
Masked);
}
+bool InstCombinerImpl::fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF,
+ const Instruction *CtxI) const {
+ KnownFPClass Known = computeKnownFPClass(MulVal, FMF, fcNegative, CtxI);
+
+ return Known.isKnownNeverNaN() && 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<FPMathOperator>(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();
@@ -3408,7 +3433,10 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
}
+ auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
+
if (auto *FCmp = dyn_cast<FCmpInst>(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) ||
@@ -3418,7 +3446,7 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
//
// 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.
@@ -3429,14 +3457,47 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
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<FPMathOperator>(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(
diff --git a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
index 753fe0d871a191..607b12b03b2a12 100644
--- a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
+++ b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
@@ -14,10 +14,7 @@ declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)
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 @@ define i32 @fcmp_zero_select_is_not_fp_unfoldable(float %x, i32 %y, i32 %z) {
; 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 @@ define float @ldexp_by_n_if_0_oeq_zero_f32(float %x, i32 %n) {
; 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]], <float 3.200000e+01, float 3.200000e+01>
-; 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, <float 32.0, float 32.0>
@@ -121,10 +112,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_splat(<2 x float> %x) {
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]], <float 3.200000e+01, float 6.400000e+01>
-; 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, <float 32.0, float 64.0>
@@ -134,10 +122,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_nonsplat(<2 x float> %x) {
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]], <float 3.200000e+01, float 3.200000e+01>
-; 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, <float 0.0, float -0.0>
%scaled.x = fmul <2 x float> %x, <float 32.0, float 32.0>
@@ -147,10 +132,7 @@ define <2 x float> @fmul_by_32_if_0_oeq_zero_v2f32_eq_mixed_zero_vector(<2 x flo
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:%.*]], <float 0.000000e+00, float poison>
-; CHECK-NEXT: [[SCALED_X:%.*]] = fmul <2 x float> [[X]], <float 3.200000e+01, float 3.200000e+01>
-; 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, <float 0.0, float poison>
%scaled.x = fmul <2 x float> %x, <float 32.0, float 32.0>
@@ -212,10 +194,7 @@ define float @fmul_by_32_if_var_oeq_zero_f32(float %x, float %y) {
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_ueq_zero_f32(float %x) {
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_negzero_f32(float %x) {
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_cmp(float %x, ptr %ptr)
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_32_if_0_oeq_zero_f32_multiple_use_fmul(float %x, ptr %ptr)
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 @@ define float @fmul_by_0_if_0_oeq_zero_f32(float %x) {
; 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_zero_else_mul_by_32(float %x) {
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_one_negzero_else_mul_by_32(float %x) {
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_zero_else_mul_by_32(float %x) {
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_one_zero_f32(float %x) {
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_oeq_zero_f32_select_nsz(float %x) {
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_var_if_0_oeq_zero_f32(float %x, float %y) {
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 @@ define float @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_ninf_select(float %x, float
; 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 @@ define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz(float %x,
; 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_fmul_nnan_ninf_select_known_never_ne
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_negzero_nsu
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 @@ define float @fmul_by_var_if_0_oeq_zero_f32_assume_finite_fmul_nsz(float %x, flo
; 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 @@ define float @fmul_by_var_if_not_one_0_zero_f32_assume_finite_fmul_nsz(float %x,
; 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
More information about the llvm-commits
mailing list