Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4506,7 +4506,16 @@ return New; } + // Sign-bit checks are preserved through signed floating-point casts: + // icmp slt (bitcast (sitofp X)), 0 --> icmp slt X, 0 + // icmp sgt (bitcast (sitofp X)), -1 --> icmp sgt X, -1 Value *X; + if (match(Op0, m_BitCast(m_SIToFP(m_Value(X))))) { + if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_Zero())) + return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); + if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes())) + return new ICmpInst(Pred, X, ConstantInt::getAllOnesValue(X->getType())); + } // Zero-equality checks are preserved through unsigned floating-point casts: // icmp eq (bitcast (uitofp X)), 0 --> icmp eq X, 0 Index: test/Transforms/InstCombine/cast-int-icmp-eq-0.ll =================================================================== --- test/Transforms/InstCombine/cast-int-icmp-eq-0.ll +++ test/Transforms/InstCombine/cast-int-icmp-eq-0.ll @@ -68,9 +68,7 @@ define i1 @i32_cast_cmp_slt_int_0_sitofp_float(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to float @@ -146,9 +144,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_sitofp_float(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to float @@ -159,9 +155,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_sitofp_float_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i32> [[I:%.*]] to <3 x float> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x float> [[F]] to <3 x i32> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i32> %i to <3 x float> @@ -224,9 +218,7 @@ define i1 @i32_cast_cmp_slt_int_0_sitofp_double(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to double @@ -302,9 +294,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_sitofp_double(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to double @@ -315,9 +305,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_sitofp_double_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i32> [[I:%.*]] to <3 x double> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x double> [[F]] to <3 x i64> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i32> %i to <3 x double> @@ -380,9 +368,7 @@ define i1 @i32_cast_cmp_slt_int_0_sitofp_half(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to half @@ -458,9 +444,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_sitofp_half(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i32 %i to half @@ -471,9 +455,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_sitofp_half_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_sitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i32> [[I:%.*]] to <3 x half> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x half> [[F]] to <3 x i16> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i32> %i to <3 x half> @@ -536,9 +518,7 @@ define i1 @i64_cast_cmp_slt_int_0_sitofp_float(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to float @@ -614,9 +594,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_sitofp_float(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to float @@ -627,9 +605,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_sitofp_float_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i64> [[I:%.*]] to <3 x float> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x float> [[F]] to <3 x i32> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i64> %i to <3 x float> @@ -692,9 +668,7 @@ define i1 @i64_cast_cmp_slt_int_0_sitofp_double(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to double @@ -770,9 +744,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_sitofp_double(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to double @@ -783,9 +755,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_sitofp_double_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i64> [[I:%.*]] to <3 x double> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x double> [[F]] to <3 x i64> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i64> %i to <3 x double> @@ -848,9 +818,7 @@ define i1 @i64_cast_cmp_slt_int_0_sitofp_half(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to half @@ -926,9 +894,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_sitofp_half(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i64 %i to half @@ -939,9 +905,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_sitofp_half_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_sitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i64> [[I:%.*]] to <3 x half> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x half> [[F]] to <3 x i16> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i64> %i to <3 x half> @@ -1004,9 +968,7 @@ define i1 @i16_cast_cmp_slt_int_0_sitofp_float(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to float @@ -1082,9 +1044,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_sitofp_float(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_float( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to float @@ -1095,9 +1055,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_sitofp_float_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x float> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x float> [[F]] to <3 x i32> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i16> %i to <3 x float> @@ -1160,9 +1118,7 @@ define i1 @i16_cast_cmp_slt_int_0_sitofp_double(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to double @@ -1238,9 +1194,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_sitofp_double(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_double( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to double @@ -1251,9 +1205,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_sitofp_double_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x double> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x double> [[F]] to <3 x i64> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i16> %i to <3 x double> @@ -1316,9 +1268,7 @@ define i1 @i16_cast_cmp_slt_int_0_sitofp_half(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[I:%.*]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to half @@ -1394,9 +1344,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_sitofp_half(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_half( -; CHECK-NEXT: [[F:%.*]] = sitofp i16 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[I:%.*]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %f = sitofp i16 %i to half @@ -1407,9 +1355,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_sitofp_half_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_sitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x half> -; CHECK-NEXT: [[B:%.*]] = bitcast <3 x half> [[F]] to <3 x i16> -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[B]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[I:%.*]], ; CHECK-NEXT: ret <3 x i1> [[CMP]] ; %f = sitofp <3 x i16> %i to <3 x half> Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -3313,29 +3313,3 @@ ret <2 x i1> %res } -define i1 @doublecast_signbit_set(i64 %x) { -; CHECK-LABEL: @doublecast_signbit_set( -; CHECK-NEXT: [[F:%.*]] = sitofp i64 [[X:%.*]] to float -; CHECK-NEXT: [[I:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[I]], 0 -; CHECK-NEXT: ret i1 [[R]] -; - %f = sitofp i64 %x to float - %i = bitcast float %f to i32 - %r = icmp slt i32 %i, 0 - ret i1 %r -} - -define <3 x i1> @doublecast_signbit_clear(<3 x i32> %x) { -; CHECK-LABEL: @doublecast_signbit_clear( -; CHECK-NEXT: [[F:%.*]] = sitofp <3 x i32> [[X:%.*]] to <3 x double> -; CHECK-NEXT: [[I:%.*]] = bitcast <3 x double> [[F]] to <3 x i64> -; CHECK-NEXT: [[R:%.*]] = icmp sgt <3 x i64> [[I]], -; CHECK-NEXT: ret <3 x i1> [[R]] -; - %f = sitofp <3 x i32> %x to <3 x double> - %i = bitcast <3 x double> %f to <3 x i64> - %r = icmp sgt <3 x i64> %i, - ret <3 x i1> %r -} -