Index: llvm/lib/Transforms/Scalar/SCCP.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SCCP.cpp +++ llvm/lib/Transforms/Scalar/SCCP.cpp @@ -173,12 +173,14 @@ Instruction *NewInst = nullptr; switch (Inst.getOpcode()) { - case Instruction::SExt: { - // If the source value is not negative, this is a zext. + case Instruction::SExt: + case Instruction::SIToFP: { + // If the source value is not negative, this is an unsigned cast. Value *Op0 = Inst.getOperand(0); - if (isa(Op0) || InsertedValues.count(Op0) || !isNonNegative(Op0)) + if (InsertedValues.count(Op0) || !isNonNegative(Op0)) return false; - NewInst = new ZExtInst(Op0, Inst.getType(), "", &Inst); + auto NewOpcode = Inst.getOpcode() == Inst.SExt ? Inst.ZExt : Inst.UIToFP; + NewInst = CastInst::Create(NewOpcode, Op0, Inst.getType(), "", &Inst); break; } case Instruction::AShr: { Index: llvm/test/Transforms/SCCP/ip-ranges-casts.ll =================================================================== --- llvm/test/Transforms/SCCP/ip-ranges-casts.ll +++ llvm/test/Transforms/SCCP/ip-ranges-casts.ll @@ -160,10 +160,11 @@ ret i1 %res } -; There's nothing we can do besides going to the full range or overdefined. +; The initial cast is known to only be used with positive values, so it becomes unsigned. + define internal i1 @f.fptosi(i32 %x) { ; CHECK-LABEL: @f.fptosi( -; CHECK-NEXT: [[TO_DOUBLE:%.*]] = sitofp i32 [[X:%.*]] to double +; CHECK-NEXT: [[TO_DOUBLE:%.*]] = uitofp i32 [[X:%.*]] to double ; CHECK-NEXT: [[ADD:%.*]] = fadd double 0.000000e+00, [[TO_DOUBLE]] ; CHECK-NEXT: [[TO_I32:%.*]] = fptosi double [[ADD]] to i32 ; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[TO_I32]], 300 @@ -202,6 +203,9 @@ } ; There's nothing we can do besides going to the full range or overdefined. +; The initial cast is used with both positive and negative values, +; so it must remain signed. + define internal i1 @f.fpext(i16 %x) { ; CHECK-LABEL: @f.fpext( ; CHECK-NEXT: [[TO_FLOAT:%.*]] = sitofp i16 [[X:%.*]] to float @@ -232,12 +236,12 @@ ; There's nothing we can do besides going to the full range or overdefined. define i1 @caller.fpext() { ; CHECK-LABEL: @caller.fpext( -; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f.fpext(i16 100) +; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f.fpext(i16 -100) ; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f.fpext(i16 300) ; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] ; CHECK-NEXT: ret i1 [[RES]] ; - %call.1 = tail call i1 @f.fpext(i16 100) + %call.1 = tail call i1 @f.fpext(i16 -100) %call.2 = tail call i1 @f.fpext(i16 300) %res = and i1 %call.1, %call.2 ret i1 %res @@ -282,11 +286,10 @@ ret i1 %res } -; Make sure we do not create constant ranges for int to fp casts. define i1 @int_range_to_double_cast(i32 %a) { ; CHECK-LABEL: @int_range_to_double_cast( ; CHECK-NEXT: [[R:%.*]] = and i32 [[A:%.*]], 255 -; CHECK-NEXT: [[T4:%.*]] = sitofp i32 [[R]] to double +; CHECK-NEXT: [[T4:%.*]] = uitofp i32 [[R]] to double ; CHECK-NEXT: [[T10:%.*]] = fadd double 0.000000e+00, [[T4]] ; CHECK-NEXT: [[T11:%.*]] = fcmp olt double [[T4]], [[T10]] ; CHECK-NEXT: ret i1 [[T11]] Index: llvm/test/Transforms/SCCP/sitofp.ll =================================================================== --- llvm/test/Transforms/SCCP/sitofp.ll +++ llvm/test/Transforms/SCCP/sitofp.ll @@ -4,7 +4,7 @@ define float @sitofp_and(i8 %x) { ; CHECK-LABEL: @sitofp_and( ; CHECK-NEXT: [[PX:%.*]] = and i8 [[X:%.*]], 127 -; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[PX]] to float +; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[PX]] to float ; CHECK-NEXT: ret float [[R]] ; %px = and i8 %x, 127 @@ -23,7 +23,7 @@ define double @sitofp_zext(i7 %x) { ; CHECK-LABEL: @sitofp_zext( ; CHECK-NEXT: [[PX:%.*]] = zext i7 [[X:%.*]] to i8 -; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[PX]] to double +; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[PX]] to double ; CHECK-NEXT: ret double [[R]] ; %px = zext i7 %x to i8 @@ -52,7 +52,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] ; CHECK: t: -; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to float +; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to float ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: f: ; CHECK-NEXT: br label [[EXIT]] @@ -86,7 +86,7 @@ ; CHECK: t: ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: f: -; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to float +; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to float ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: [[COND:%.*]] = phi float [ -4.200000e+01, [[T]] ], [ [[A]], [[F]] ]