[llvm] a597ff3 - InstCombine: Add baseline tests for select on compare of fcmp 0 pattern

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 28 17:07:00 PDT 2023


Author: Matt Arsenault
Date: 2023-08-28T20:06:25-04:00
New Revision: a597ff31c8663478f4a160f99572d099e6f519ae

URL: https://github.com/llvm/llvm-project/commit/a597ff31c8663478f4a160f99572d099e6f519ae
DIFF: https://github.com/llvm/llvm-project/commit/a597ff31c8663478f4a160f99572d099e6f519ae.diff

LOG: InstCombine: Add baseline tests for select on compare of fcmp 0 pattern

Added: 
    llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
new file mode 100644
index 00000000000000..753fe0d871a191
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
@@ -0,0 +1,805 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --scrub-attributes
+; RUN: opt -S -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,IEEE %s
+; RUN: opt -S -passes=instcombine -denormal-fp-math=preserve-sign < %s | FileCheck -check-prefixes=CHECK,DAZ  %s
+; RUN: opt -S -passes=instcombine -denormal-fp-math=positive-zero < %s | FileCheck -check-prefixes=CHECK,DAPZ  %s
+
+; Test for patterns that appear when denormal range checks are folded
+; to compares to 0, which drop canonicalizing
+
+declare void @llvm.assume(i1 noundef)
+declare float @llvm.fabs.f32(float)
+declare float @llvm.ldexp.f32.i32(float, i32)
+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:    ret i32 [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %bitcast.scaled.x = bitcast float %scaled.x to i32
+  %bitcast.x = bitcast float %x to i32
+  %scaled.if.denormal = select i1 %x.is.zero, i32 %bitcast.scaled.x, i32 %bitcast.x
+  ret i32 %scaled.if.denormal
+}
+
+define i32 @fcmp_zero_select_is_not_fp_unfoldable(float %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @fcmp_zero_select_is_not_fp_unfoldable(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], i32 [[Y:%.*]], i32 [[Z:%.*]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %select = select i1 %x.is.zero, i32 %y, i32 %z
+  ret i32 %select
+}
+
+; 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @ldexp_by_5_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @ldexp_by_5_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 5)
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = call float @llvm.ldexp.f32.i32(float %x, i32 5)
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define <2 x float> @ldexp_by_5_if_0_oeq_zero_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @ldexp_by_5_if_0_oeq_zero_v2f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[SCALED_X:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> <i32 5, i32 5>)
+; 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]]
+;
+  %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
+  %scaled.x = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 5, i32 5>)
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+define <2 x float> @ldexp_by_n_if_0_oeq_zero_v2f32(<2 x float> %x, <2 x i32> %n) {
+; CHECK-LABEL: @ldexp_by_n_if_0_oeq_zero_v2f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[SCALED_X:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[N:%.*]])
+; 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]]
+;
+  %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
+  %scaled.x = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %n)
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+define float @ldexp_by_n_if_0_oeq_zero_f32(float %x, i32 %n) {
+; CHECK-LABEL: @ldexp_by_n_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[N:%.*]])
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; 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]]
+;
+  %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
+  %scaled.x = fmul <2 x float> %x, <float 32.0, float 32.0>
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
+  %scaled.x = fmul <2 x float> %x, <float 32.0, float 64.0>
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+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]]
+;
+  %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>
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+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]]
+;
+  %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>
+  %scaled.if.denormal = select <2 x i1> %x.is.zero, <2 x float> %scaled.x, <2 x float> %x
+  ret <2 x float> %scaled.if.denormal
+}
+
+define float @select_wrong_value(float %x, float %y) {
+; CHECK-LABEL: @select_wrong_value(
+; 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 [[Y:%.*]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %y
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_wrong_value(float %x, float %y) {
+; CHECK-LABEL: @fmul_wrong_value(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul float [[Y:%.*]], 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %y, 32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; wrong compared constant
+define float @fmul_by_32_if_1_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_32_if_1_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ONE:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ONE]], float 3.200000e+01, float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.one = fcmp oeq float %x, 1.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.one, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_32_if_var_oeq_zero_f32(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_32_if_var_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ONE:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul float [[X]], 3.200000e+01
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ONE]], float [[SCALED_X]], float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.one = fcmp oeq float %x, %y
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.one, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp ueq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, -0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  store i1 %x.is.zero, ptr %ptr
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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:    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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  store float %scaled.x, ptr %ptr
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 0.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; 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]]
+;
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.not.zero = fcmp one float %x, -0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.not.zero = fcmp une float %x, 0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.not.zero = fcmp une float %x, -0.0
+  %scaled.x = fmul float %x, 32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neg32_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_neg32_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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, -32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neg32_if_0_one_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_neg32_if_0_one_zero_f32(
+; 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]]
+;
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul float %x, -32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, -32.0
+  %scaled.if.denormal = select nsz i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul float %x, -32.0
+  %scaled.if.denormal = select nsz i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neg32_if_0_oeq_zero_f32_fmul_nsz(float %x) {
+; CHECK-LABEL: @fmul_by_neg32_if_0_oeq_zero_f32_fmul_nsz(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul nsz 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nsz float %x, -32.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neg32_if_0_one_zero_f32_mul_nsz(float %x) {
+; CHECK-LABEL: @fmul_by_neg32_if_0_one_zero_f32_mul_nsz(
+; CHECK-NEXT:    [[X_IS_NOT_ZERO:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul nsz 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]]
+;
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul nsz float %x, -32.0
+  %scaled.if.denormal = select i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neg0_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_neg0_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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, -0.0
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_neginf_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_neginf_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul float [[X]], 0xFFF0000000000000
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 0xFFF0000000000000
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_posinf_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_posinf_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = fmul float [[X]], 0x7FF0000000000000
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 0x7FF0000000000000
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_qnan_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_qnan_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 0x7FF8000000000000
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_snan_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_snan_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float 0x7FF8800000000000, float [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, 0x7FF0800000000000
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_var_if_0_oeq_zero_f32(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32(
+; 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_fabs_var_if_0_oeq_zero_f32(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_fabs_var_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[Y_FABS:%.*]] = call 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]]
+;
+  %y.fabs = call float @llvm.fabs.f32(float %y)
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y.fabs
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %y.fabs = call nnan ninf float @llvm.fabs.f32(float %y)
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y.fabs
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; nsz is not sufficient
+define float @fmul_by_var_if_0_oeq_zero_f32_nsz_fmul(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_fmul(
+; 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 nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nsz float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; nsz ninf is not sufficient
+define float @fmul_by_var_if_0_oeq_zero_f32_nsz_ninf_fmul(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_ninf_fmul(
+; 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 ninf nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nsz ninf float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; nsz nnan is not sufficient
+define float @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_fmul(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_fmul(
+; 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 nnan nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nsz nnan float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; nnan ninf is not sufficient
+define float @fmul_by_var_if_0_oeq_zero_f32_nnan_ninf_fmul(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nnan_ninf_fmul(
+; 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 nnan ninf float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; nsz nnan ninf is sufficient, but not useful on the select
+define float @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_ninf_select(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_ninf_select(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = select nnan ninf 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select nsz nnan ninf i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf float %x, %y
+  %scaled.if.denormal = select nsz i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; 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]]
+;
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul nnan ninf float %x, %y
+  %scaled.if.denormal = select nsz i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(
+; 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 nnan ninf nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf nsz float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz_commuted(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz_commuted(
+; 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 nnan ninf nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf nsz float %y, %x
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; test computeKnownFPClass is checked
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero(float %x, float nofpclass(nzero) %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero(
+; 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 nnan ninf float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero_negsub(float %x, float nofpclass(nzero nsub) %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero_negsub(
+; 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 nnan ninf float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select nsz i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; Infer everything from incoming multiplied value
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero(float %x, float nofpclass(nan inf nzero) %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero(
+; 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero_nsub(float %x, float nofpclass(nan inf nzero nsub) %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero_nsub(
+; 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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+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]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; Test assume of y works
+define float @fmul_by_var_if_0_oeq_zero_f32_assume_finite_fmul_nsz(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_assume_finite_fmul_nsz(
+; 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]]
+;
+  %fabs.y = call float @llvm.fabs.f32(float %y)
+  %is.finite = fcmp olt float %fabs.y, 0x7FF0000000000000
+  call void @llvm.assume(i1 %is.finite)
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select nsz i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+; Test assume of y works in inverted case
+define float @fmul_by_var_if_not_one_0_zero_f32_assume_finite_fmul_nsz(float %x, float %y) {
+; CHECK-LABEL: @fmul_by_var_if_not_one_0_zero_f32_assume_finite_fmul_nsz(
+; 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]]
+;
+  %fabs.y = call float @llvm.fabs.f32(float %y)
+  %is.finite = fcmp olt float %fabs.y, 0x7FF0000000000000
+  call void @llvm.assume(i1 %is.finite)
+  %x.is.not.zero = fcmp one float %x, 0.0
+  %scaled.x = fmul float %x, %y
+  %scaled.if.denormal = select nsz i1 %x.is.not.zero, float %x, float %scaled.x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_self_if_0_oeq_zero_f32(float %x) {
+; CHECK-LABEL: @fmul_by_self_if_0_oeq_zero_f32(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %x
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_self_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(float %x) {
+; CHECK-LABEL: @fmul_by_self_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf nsz float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul nnan ninf nsz float %x, %x
+  %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+define float @fmul_by_self_if_0_oeq_zero_f32_select_nnan_ninf_nsz(float %x) {
+; CHECK-LABEL: @fmul_by_self_if_0_oeq_zero_f32_select_nnan_ninf_nsz(
+; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[SCALED_X:%.*]] = select nnan ninf nsz i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]]
+; CHECK-NEXT:    ret float [[SCALED_IF_DENORMAL]]
+;
+  %x.is.zero = fcmp oeq float %x, 0.0
+  %scaled.x = fmul float %x, %x
+  %scaled.if.denormal = select nnan ninf nsz i1 %x.is.zero, float %scaled.x, float %x
+  ret float %scaled.if.denormal
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; DAPZ: {{.*}}
+; DAZ: {{.*}}
+; IEEE: {{.*}}


        


More information about the llvm-commits mailing list