Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4515,6 +4515,17 @@ return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); } + // Sign-bit checks can be optimized to true/false after unsigned + // floating-point casts: + // icmp slt (bitcast (uitofp X)), 0 --> false + // icmp sgt (bitcast (uitofp X)), -1 --> true + if (match(Op0, m_BitCast(m_UIToFP(m_Value(X))))) { + if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_Zero())) + return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); + if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes())) + return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); + } + // Test to see if the operands of the icmp are casted versions of other // values. If the ptr->ptr cast can be stripped off both arguments, we do so // now. Index: test/Transforms/InstCombine/cast-unsigned-icmp-cmp-0.ll =================================================================== --- test/Transforms/InstCombine/cast-unsigned-icmp-cmp-0.ll +++ test/Transforms/InstCombine/cast-unsigned-icmp-cmp-0.ll @@ -12,10 +12,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_float(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i32 %i to float %b = bitcast float %f to i32 @@ -38,10 +35,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i32 %i to float %b = bitcast float %f to i32 @@ -51,10 +45,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i32> %i to <3 x float> %b = bitcast <3 x float> %f to <3 x i32> @@ -64,10 +55,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i32 %i to double %b = bitcast double %f to i64 @@ -90,10 +78,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i32 %i to double %b = bitcast double %f to i64 @@ -103,10 +88,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i32> %i to <3 x double> %b = bitcast <3 x double> %f to <3 x i64> @@ -116,10 +98,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i32 %i to half %b = bitcast half %f to i16 @@ -142,10 +121,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i32 %i to half %b = bitcast half %f to i16 @@ -155,10 +131,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(<3 x i32> %i) { ; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i32> %i to <3 x half> %b = bitcast <3 x half> %f to <3 x i16> @@ -168,10 +141,7 @@ define i1 @i64_cast_cmp_slt_int_0_uitofp_float(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i64 %i to float %b = bitcast float %f to i32 @@ -194,10 +164,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_uitofp_float(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i64 %i to float %b = bitcast float %f to i32 @@ -207,10 +174,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_uitofp_float_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i64> %i to <3 x float> %b = bitcast <3 x float> %f to <3 x i32> @@ -220,10 +184,7 @@ define i1 @i64_cast_cmp_slt_int_0_uitofp_double(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i64 %i to double %b = bitcast double %f to i64 @@ -246,10 +207,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_uitofp_double(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i64 %i to double %b = bitcast double %f to i64 @@ -259,10 +217,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_uitofp_double_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i64> %i to <3 x double> %b = bitcast <3 x double> %f to <3 x i64> @@ -272,10 +227,7 @@ define i1 @i64_cast_cmp_slt_int_0_uitofp_half(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_slt_int_0_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i64 %i to half %b = bitcast half %f to i16 @@ -298,10 +250,7 @@ define i1 @i64_cast_cmp_sgt_int_m1_uitofp_half(i64 %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i64 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i64 %i to half %b = bitcast half %f to i16 @@ -311,10 +260,7 @@ define <3 x i1> @i64_cast_cmp_sgt_int_m1_uitofp_half_vec(<3 x i64> %i) { ; CHECK-LABEL: @i64_cast_cmp_sgt_int_m1_uitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i64> %i to <3 x half> %b = bitcast <3 x half> %f to <3 x i16> @@ -324,10 +270,7 @@ define i1 @i16_cast_cmp_slt_int_0_uitofp_float(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i16 %i to float %b = bitcast float %f to i32 @@ -350,10 +293,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_uitofp_float(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_float( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to float -; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i16 %i to float %b = bitcast float %f to i32 @@ -363,10 +303,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_uitofp_float_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_float_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i16> %i to <3 x float> %b = bitcast <3 x float> %f to <3 x i32> @@ -376,10 +313,7 @@ define i1 @i16_cast_cmp_slt_int_0_uitofp_double(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i16 %i to double %b = bitcast double %f to i64 @@ -402,10 +336,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_uitofp_double(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_double( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to double -; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i16 %i to double %b = bitcast double %f to i64 @@ -415,10 +346,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_uitofp_double_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_double_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i16> %i to <3 x double> %b = bitcast <3 x double> %f to <3 x i64> @@ -428,10 +356,7 @@ define i1 @i16_cast_cmp_slt_int_0_uitofp_half(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_slt_int_0_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %f = uitofp i16 %i to half %b = bitcast half %f to i16 @@ -454,10 +379,7 @@ define i1 @i16_cast_cmp_sgt_int_m1_uitofp_half(i16 %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_half( -; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[I:%.*]] to half -; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %f = uitofp i16 %i to half %b = bitcast half %f to i16 @@ -467,10 +389,7 @@ define <3 x i1> @i16_cast_cmp_sgt_int_m1_uitofp_half_vec(<3 x i16> %i) { ; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_uitofp_half_vec( -; CHECK-NEXT: [[F:%.*]] = uitofp <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: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> ; %f = uitofp <3 x i16> %i to <3 x half> %b = bitcast <3 x half> %f to <3 x i16>