diff --git a/llvm/test/Transforms/InstCombine/known-bits-bitcast-from-fp.ll b/llvm/test/Transforms/InstCombine/known-bits-bitcast-from-fp.ll new file mode 100644 index 0000000000000..ff707b8824365 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/known-bits-bitcast-from-fp.ll @@ -0,0 +1,360 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes=instcombine < %s | FileCheck %s + +define i1 @test_sign_pos(float %x) { +; CHECK-LABEL: @test_sign_pos( +; CHECK-NEXT: ret i1 true +; + %fabs = call float @llvm.fabs.f32(float %x) + %y = bitcast float %fabs to i32 + %sign = icmp sgt i32 %y, -1 + ret i1 %sign +} + +define i1 @test_sign_pos_half(half %x) { +; CHECK-LABEL: @test_sign_pos_half( +; CHECK-NEXT: ret i1 true +; + %fabs = call half @llvm.fabs.f16(half %x) + %y = bitcast half %fabs to i16 + %sign = icmp sgt i16 %y, -1 + ret i1 %sign +} + +define i1 @test_sign_pos_half_non_elementwise(<2 x half> %x) { +; CHECK-LABEL: @test_sign_pos_half_non_elementwise( +; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) +; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x half> [[FABS]] to i32 +; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1 +; CHECK-NEXT: ret i1 [[SIGN]] +; + %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) + %y = bitcast <2 x half> %fabs to i32 + %sign = icmp sgt i32 %y, -1 + ret i1 %sign +} + +define i1 @test_sign_neg(float %x) { +; CHECK-LABEL: @test_sign_neg( +; CHECK-NEXT: ret i1 true +; + %fabs = call float @llvm.fabs.f32(float %x) + %fnabs = fneg float %fabs + %y = bitcast float %fnabs to i32 + %sign = icmp slt i32 %y, 0 + ret i1 %sign +} + +define <2 x i1> @test_sign_pos_vec(<2 x float> %x) { +; CHECK-LABEL: @test_sign_pos_vec( +; CHECK-NEXT: ret <2 x i1> zeroinitializer +; + %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x) + %y = bitcast <2 x float> %fabs to <2 x i32> + %sign = icmp slt <2 x i32> %y, zeroinitializer + ret <2 x i1> %sign +} + +define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) { +; CHECK-LABEL: @test_inf_only( +; CHECK-NEXT: ret i32 2139095040 +; + %y = bitcast float %x to i32 + %and = and i32 %y, 2147483647 + ret i32 %and +} + +define i16 @test_inf_only_bfloat(bfloat nofpclass(nan sub norm zero) %x) { +; CHECK-LABEL: @test_inf_only_bfloat( +; CHECK-NEXT: ret i16 32640 +; + %y = bitcast bfloat %x to i16 + %and = and i16 %y, 32767 + ret i16 %and +} + +define i128 @test_inf_only_ppc_fp128(ppc_fp128 nofpclass(nan sub norm zero) %x) { +; CHECK-LABEL: @test_inf_only_ppc_fp128( +; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X:%.*]]) +; CHECK-NEXT: [[AND:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128 +; CHECK-NEXT: ret i128 [[AND]] +; + %y = bitcast ppc_fp128 %x to i128 + %and = and i128 %y, 170141183460469231731687303715884105727 + ret i128 %and +} + +define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) { +; CHECK-LABEL: @test_zero_only( +; CHECK-NEXT: ret i32 0 +; + %y = bitcast float %x to i32 + %and = and i32 %y, 2147483647 + ret i32 %and +} + +define i80 @test_zero_only_non_ieee(x86_fp80 nofpclass(nan sub norm inf) %x) { +; CHECK-LABEL: @test_zero_only_non_ieee( +; CHECK-NEXT: ret i80 0 +; + %y = bitcast x86_fp80 %x to i80 + %and = and i80 %y, 604462909807314587353087 + ret i80 %and +} + +define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) { +; CHECK-LABEL: @test_inf_nan_only( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 2130706432 + ret i32 %and +} + +define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) { +; CHECK-LABEL: @test_sub_zero_only( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 2130706432 + ret i32 %and +} + +define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) { +; CHECK-LABEL: @test_inf_zero_only( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 8388608 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 16777215 + ret i32 %and +} + +; Make sure that the signbit is cleared. +define i32 @test_ninf_only(double %x) { +; CHECK-LABEL: @test_ninf_only( +; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[X:%.*]], -inf +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: ret i32 0 +; CHECK: if.else: +; CHECK-NEXT: ret i32 0 +; + %cmp = fcmp oeq double %x, -inf + br i1 %cmp, label %if.then, label %if.else + +if.then: + %cast = bitcast double %x to i64 + %trunc = trunc i64 %cast to i32 + ret i32 %trunc + +if.else: + ret i32 0 +} + +define i1 @test_simplify_icmp(i32 %x) { +; CHECK-LABEL: @test_simplify_icmp( +; CHECK-NEXT: ret i1 false +; + %cast1 = uitofp i32 %x to double + %cast2 = bitcast double %cast1 to i64 + %mask = and i64 %cast2, -140737488355328 + %cmp = icmp eq i64 %mask, -1970324836974592 + ret i1 %cmp +} + +define i32 @test_snan_quiet_bit1(float nofpclass(sub norm inf qnan) %x) { +; CHECK-LABEL: @test_snan_quiet_bit1( +; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 +; CHECK-NEXT: ret i32 [[MASKED]] +; + %bits = bitcast float %x to i32 + %masked = and i32 %bits, 4194304 + ret i32 %masked +} + +define i32 @test_snan_quiet_bit2(float nofpclass(sub norm inf qnan) %x) { +; CHECK-LABEL: @test_snan_quiet_bit2( +; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 +; CHECK-NEXT: ret i32 [[MASKED]] +; + %bits = bitcast float %x to i32 + %masked = and i32 %bits, 2097152 + ret i32 %masked +} + +define i32 @test_qnan_quiet_bit1(float nofpclass(sub norm inf snan) %x) { +; CHECK-LABEL: @test_qnan_quiet_bit1( +; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 +; CHECK-NEXT: ret i32 [[MASKED]] +; + %bits = bitcast float %x to i32 + %masked = and i32 %bits, 4194304 + ret i32 %masked +} + +define i32 @test_qnan_quiet_bit2(float nofpclass(sub norm inf snan) %x) { +; CHECK-LABEL: @test_qnan_quiet_bit2( +; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 +; CHECK-NEXT: ret i32 [[MASKED]] +; + %bits = bitcast float %x to i32 + %masked = and i32 %bits, 2097152 + ret i32 %masked +} + +define i16 @test_simplify_mask(i32 %ui, float %x) { +; CHECK-LABEL: @test_simplify_mask( +; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float +; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[CONV]] +; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]] +; CHECK: if.end: +; CHECK-NEXT: ret i16 31744 +; CHECK: if.else: +; CHECK-NEXT: ret i16 0 +; + %conv = uitofp i32 %ui to float + %cmp = fcmp olt float %x, %conv + br i1 %cmp, label %if.else, label %if.end + +if.end: + %cast = bitcast float %conv to i32 + %shr = lshr i32 %cast, 16 + %trunc = trunc i32 %shr to i16 + %and = and i16 %trunc, -32768 + %or = or disjoint i16 %and, 31744 + ret i16 %or + +if.else: + ret i16 0 +} + +define i1 @test_simplify_icmp2(double %x) { +; CHECK-LABEL: @test_simplify_icmp2( +; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) +; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], +inf +; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: ret i1 false +; CHECK: if.else: +; CHECK-NEXT: ret i1 false +; + %abs = tail call double @llvm.fabs.f64(double %x) + %cond = fcmp oeq double %abs, +inf + br i1 %cond, label %if.then, label %if.else + +if.then: + %cast = bitcast double %x to i64 + %cmp = icmp eq i64 %cast, 3458764513820540928 + ret i1 %cmp + +if.else: + ret i1 false +} + +define i32 @test_snan_only(float nofpclass(qnan sub norm zero inf) %x) { +; CHECK-LABEL: @test_snan_only( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 4194304 + ret i32 %and +} + +define i32 @test_qnan_only(float nofpclass(snan sub norm zero inf) %x) { +; CHECK-LABEL: @test_qnan_only( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 4194304 + ret i32 %and +} + +; Make sure that we don't crash when the use of x is unreachable. +define i64 @pr92084(double %x) { +; CHECK-LABEL: @pr92084( +; CHECK-NEXT: [[CMP:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00 +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then1: +; CHECK-NEXT: br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]] +; CHECK: if.then2: +; CHECK-NEXT: ret i64 poison +; CHECK: if.else: +; CHECK-NEXT: ret i64 0 +; + %cmp = fcmp uno double %x, 0.000000e+00 + br i1 %cmp, label %if.then1, label %if.else + +if.then1: + br i1 %cmp, label %if.else, label %if.then2 + +if.then2: + %cast = bitcast double %x to i64 + %and = and i64 %cast, 1 + ret i64 %and + +if.else: + ret i64 0 +} + +define i32 @test_none(float nofpclass(all) %x) { +; CHECK-LABEL: @test_none( +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 +; CHECK-NEXT: ret i32 [[AND]] +; + %y = bitcast float %x to i32 + %and = and i32 %y, 4194304 + ret i32 %and +} + +; We cannot make assumptions about the sign of result of sqrt +; when the input is a negative value (except for -0). +define i1 @pr92217() { +; CHECK-LABEL: @pr92217( +; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float f0xF6F5F4F3) +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000) + %y = bitcast float %x to i32 + %cmp = icmp slt i32 %y, 0 + ret i1 %cmp +} + +define i1 @sqrt_negative_input(float nofpclass(nan zero pnorm psub pinf) %a) { +; CHECK-LABEL: @sqrt_negative_input( +; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]]) +; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %x = call float @llvm.sqrt.f32(float %a) + %y = bitcast float %x to i32 + %cmp = icmp slt i32 %y, 0 + ret i1 %cmp +} + +define i1 @sqrt_negative_input_nnan(float nofpclass(nan zero pnorm psub pinf) %a) { +; CHECK-LABEL: @sqrt_negative_input_nnan( +; CHECK-NEXT: ret i1 false +; + %x = call nnan float @llvm.sqrt.f32(float %a) + %y = bitcast float %x to i32 + %cmp = icmp slt i32 %y, 0 + ret i1 %cmp +} diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll index f7d8ff7fffbbe..38f75d75e10d9 100644 --- a/llvm/test/Transforms/InstCombine/known-bits.ll +++ b/llvm/test/Transforms/InstCombine/known-bits.ll @@ -1465,364 +1465,6 @@ define i8 @nonzero_reduce_xor_vscale_odd( %xx) { ret i8 %r } -define i1 @test_sign_pos(float %x) { -; CHECK-LABEL: @test_sign_pos( -; CHECK-NEXT: ret i1 true -; - %fabs = call float @llvm.fabs.f32(float %x) - %y = bitcast float %fabs to i32 - %sign = icmp sgt i32 %y, -1 - ret i1 %sign -} - -define i1 @test_sign_pos_half(half %x) { -; CHECK-LABEL: @test_sign_pos_half( -; CHECK-NEXT: ret i1 true -; - %fabs = call half @llvm.fabs.f16(half %x) - %y = bitcast half %fabs to i16 - %sign = icmp sgt i16 %y, -1 - ret i1 %sign -} - -define i1 @test_sign_pos_half_non_elementwise(<2 x half> %x) { -; CHECK-LABEL: @test_sign_pos_half_non_elementwise( -; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) -; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x half> [[FABS]] to i32 -; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1 -; CHECK-NEXT: ret i1 [[SIGN]] -; - %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) - %y = bitcast <2 x half> %fabs to i32 - %sign = icmp sgt i32 %y, -1 - ret i1 %sign -} - -define i1 @test_sign_neg(float %x) { -; CHECK-LABEL: @test_sign_neg( -; CHECK-NEXT: ret i1 true -; - %fabs = call float @llvm.fabs.f32(float %x) - %fnabs = fneg float %fabs - %y = bitcast float %fnabs to i32 - %sign = icmp slt i32 %y, 0 - ret i1 %sign -} - -define <2 x i1> @test_sign_pos_vec(<2 x float> %x) { -; CHECK-LABEL: @test_sign_pos_vec( -; CHECK-NEXT: ret <2 x i1> zeroinitializer -; - %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x) - %y = bitcast <2 x float> %fabs to <2 x i32> - %sign = icmp slt <2 x i32> %y, zeroinitializer - ret <2 x i1> %sign -} - -define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) { -; CHECK-LABEL: @test_inf_only( -; CHECK-NEXT: ret i32 2139095040 -; - %y = bitcast float %x to i32 - %and = and i32 %y, 2147483647 - ret i32 %and -} - -define i16 @test_inf_only_bfloat(bfloat nofpclass(nan sub norm zero) %x) { -; CHECK-LABEL: @test_inf_only_bfloat( -; CHECK-NEXT: ret i16 32640 -; - %y = bitcast bfloat %x to i16 - %and = and i16 %y, 32767 - ret i16 %and -} - -define i128 @test_inf_only_ppc_fp128(ppc_fp128 nofpclass(nan sub norm zero) %x) { -; CHECK-LABEL: @test_inf_only_ppc_fp128( -; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X:%.*]]) -; CHECK-NEXT: [[AND:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128 -; CHECK-NEXT: ret i128 [[AND]] -; - %y = bitcast ppc_fp128 %x to i128 - %and = and i128 %y, 170141183460469231731687303715884105727 - ret i128 %and -} - -define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) { -; CHECK-LABEL: @test_zero_only( -; CHECK-NEXT: ret i32 0 -; - %y = bitcast float %x to i32 - %and = and i32 %y, 2147483647 - ret i32 %and -} - -define i80 @test_zero_only_non_ieee(x86_fp80 nofpclass(nan sub norm inf) %x) { -; CHECK-LABEL: @test_zero_only_non_ieee( -; CHECK-NEXT: ret i80 0 -; - %y = bitcast x86_fp80 %x to i80 - %and = and i80 %y, 604462909807314587353087 - ret i80 %and -} - -define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) { -; CHECK-LABEL: @test_inf_nan_only( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 2130706432 - ret i32 %and -} - -define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) { -; CHECK-LABEL: @test_sub_zero_only( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 2130706432 - ret i32 %and -} - -define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) { -; CHECK-LABEL: @test_inf_zero_only( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 8388608 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 16777215 - ret i32 %and -} - -; Make sure that the signbit is cleared. -define i32 @test_ninf_only(double %x) { -; CHECK-LABEL: @test_ninf_only( -; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[X:%.*]], -inf -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; CHECK: if.then: -; CHECK-NEXT: ret i32 0 -; CHECK: if.else: -; CHECK-NEXT: ret i32 0 -; - %cmp = fcmp oeq double %x, -inf - br i1 %cmp, label %if.then, label %if.else - -if.then: - %cast = bitcast double %x to i64 - %trunc = trunc i64 %cast to i32 - ret i32 %trunc - -if.else: - ret i32 0 -} - -define i1 @test_simplify_icmp(i32 %x) { -; CHECK-LABEL: @test_simplify_icmp( -; CHECK-NEXT: ret i1 false -; - %cast1 = uitofp i32 %x to double - %cast2 = bitcast double %cast1 to i64 - %mask = and i64 %cast2, -140737488355328 - %cmp = icmp eq i64 %mask, -1970324836974592 - ret i1 %cmp -} - -define i32 @test_snan_quiet_bit1(float nofpclass(sub norm inf qnan) %x) { -; CHECK-LABEL: @test_snan_quiet_bit1( -; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 -; CHECK-NEXT: ret i32 [[MASKED]] -; - %bits = bitcast float %x to i32 - %masked = and i32 %bits, 4194304 - ret i32 %masked -} - -define i32 @test_snan_quiet_bit2(float nofpclass(sub norm inf qnan) %x) { -; CHECK-LABEL: @test_snan_quiet_bit2( -; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 -; CHECK-NEXT: ret i32 [[MASKED]] -; - %bits = bitcast float %x to i32 - %masked = and i32 %bits, 2097152 - ret i32 %masked -} - -define i32 @test_qnan_quiet_bit1(float nofpclass(sub norm inf snan) %x) { -; CHECK-LABEL: @test_qnan_quiet_bit1( -; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 -; CHECK-NEXT: ret i32 [[MASKED]] -; - %bits = bitcast float %x to i32 - %masked = and i32 %bits, 4194304 - ret i32 %masked -} - -define i32 @test_qnan_quiet_bit2(float nofpclass(sub norm inf snan) %x) { -; CHECK-LABEL: @test_qnan_quiet_bit2( -; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 -; CHECK-NEXT: ret i32 [[MASKED]] -; - %bits = bitcast float %x to i32 - %masked = and i32 %bits, 2097152 - ret i32 %masked -} - -define i16 @test_simplify_mask(i32 %ui, float %x) { -; CHECK-LABEL: @test_simplify_mask( -; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[CONV]] -; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]] -; CHECK: if.end: -; CHECK-NEXT: ret i16 31744 -; CHECK: if.else: -; CHECK-NEXT: ret i16 0 -; - %conv = uitofp i32 %ui to float - %cmp = fcmp olt float %x, %conv - br i1 %cmp, label %if.else, label %if.end - -if.end: - %cast = bitcast float %conv to i32 - %shr = lshr i32 %cast, 16 - %trunc = trunc i32 %shr to i16 - %and = and i16 %trunc, -32768 - %or = or disjoint i16 %and, 31744 - ret i16 %or - -if.else: - ret i16 0 -} - -define i1 @test_simplify_icmp2(double %x) { -; CHECK-LABEL: @test_simplify_icmp2( -; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) -; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], +inf -; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; CHECK: if.then: -; CHECK-NEXT: ret i1 false -; CHECK: if.else: -; CHECK-NEXT: ret i1 false -; - %abs = tail call double @llvm.fabs.f64(double %x) - %cond = fcmp oeq double %abs, +inf - br i1 %cond, label %if.then, label %if.else - -if.then: - %cast = bitcast double %x to i64 - %cmp = icmp eq i64 %cast, 3458764513820540928 - ret i1 %cmp - -if.else: - ret i1 false -} - -define i32 @test_snan_only(float nofpclass(qnan sub norm zero inf) %x) { -; CHECK-LABEL: @test_snan_only( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 4194304 - ret i32 %and -} - -define i32 @test_qnan_only(float nofpclass(snan sub norm zero inf) %x) { -; CHECK-LABEL: @test_qnan_only( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 4194304 - ret i32 %and -} - -; Make sure that we don't crash when the use of x is unreachable. -define i64 @pr92084(double %x) { -; CHECK-LABEL: @pr92084( -; CHECK-NEXT: [[CMP:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]] -; CHECK: if.then1: -; CHECK-NEXT: br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]] -; CHECK: if.then2: -; CHECK-NEXT: ret i64 poison -; CHECK: if.else: -; CHECK-NEXT: ret i64 0 -; - %cmp = fcmp uno double %x, 0.000000e+00 - br i1 %cmp, label %if.then1, label %if.else - -if.then1: - br i1 %cmp, label %if.else, label %if.then2 - -if.then2: - %cast = bitcast double %x to i64 - %and = and i64 %cast, 1 - ret i64 %and - -if.else: - ret i64 0 -} - -define i32 @test_none(float nofpclass(all) %x) { -; CHECK-LABEL: @test_none( -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 -; CHECK-NEXT: ret i32 [[AND]] -; - %y = bitcast float %x to i32 - %and = and i32 %y, 4194304 - ret i32 %and -} - -; We cannot make assumptions about the sign of result of sqrt -; when the input is a negative value (except for -0). -define i1 @pr92217() { -; CHECK-LABEL: @pr92217( -; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float f0xF6F5F4F3) -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 -; CHECK-NEXT: ret i1 [[CMP]] -; - %x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000) - %y = bitcast float %x to i32 - %cmp = icmp slt i32 %y, 0 - ret i1 %cmp -} - -define i1 @sqrt_negative_input(float nofpclass(nan zero pnorm psub pinf) %a) { -; CHECK-LABEL: @sqrt_negative_input( -; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]]) -; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 -; CHECK-NEXT: ret i1 [[CMP]] -; - %x = call float @llvm.sqrt.f32(float %a) - %y = bitcast float %x to i32 - %cmp = icmp slt i32 %y, 0 - ret i1 %cmp -} - -define i1 @sqrt_negative_input_nnan(float nofpclass(nan zero pnorm psub pinf) %a) { -; CHECK-LABEL: @sqrt_negative_input_nnan( -; CHECK-NEXT: ret i1 false -; - %x = call nnan float @llvm.sqrt.f32(float %a) - %y = bitcast float %x to i32 - %cmp = icmp slt i32 %y, 0 - ret i1 %cmp -} - define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) { ; CHECK-LABEL: @test_icmp_add( ; CHECK-NEXT: entry: