Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4506,6 +4506,17 @@ 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())); + } + // 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/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -3315,9 +3315,7 @@ 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: [[R:%.*]] = icmp slt i64 [[X:%.*]], 0 ; CHECK-NEXT: ret i1 [[R]] ; %f = sitofp i64 %x to float @@ -3328,9 +3326,7 @@ 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: [[R:%.*]] = icmp sgt <3 x i32> [[X:%.*]], ; CHECK-NEXT: ret <3 x i1> [[R]] ; %f = sitofp <3 x i32> %x to <3 x double>