[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