diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp index de8c05d5689f5..7e862882310b8 100644 --- a/llvm/lib/Transforms/Scalar/Float2Int.cpp +++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp @@ -407,11 +407,10 @@ Value *Float2IntPass::convert(Instruction *I, Type *ToTy) { } else if (Instruction *VI = dyn_cast(V)) { NewOperands.push_back(convert(VI, ToTy)); } else if (ConstantFP *CF = dyn_cast(V)) { - APSInt Val(ToTy->getPrimitiveSizeInBits(), /*isUnsigned=*/false); + const APFloat &F = CF->getValueAPF(); + APSInt Val(ToTy->getPrimitiveSizeInBits(), !F.isNegative()); bool Exact; - CF->getValueAPF().convertToInteger(Val, - APFloat::rmNearestTiesToEven, - &Exact); + F.convertToInteger(Val, APFloat::rmNearestTiesToEven, &Exact); NewOperands.push_back(ConstantInt::get(ToTy, Val)); } else { llvm_unreachable("Unhandled operand type?"); diff --git a/llvm/test/Transforms/Float2Int/basic.ll b/llvm/test/Transforms/Float2Int/basic.ll index 2854a83179b7e..5d923ec217c8d 100644 --- a/llvm/test/Transforms/Float2Int/basic.ll +++ b/llvm/test/Transforms/Float2Int/basic.ll @@ -349,3 +349,57 @@ bogusBB: ; preds = %bogusBB %tobool = fcmp une double %inc, 0.000000e+00 br label %bogusBB } + +define i32 @pr79158() { +; CHECK-LABEL: @pr79158( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X_I:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X_I]]) +; CHECK-NEXT: store volatile i32 1, ptr [[X_I]], align 4 +; CHECK-NEXT: [[X_I_0_X_I_0_X_0_X_0_X_0__I:%.*]] = load volatile i32, ptr [[X_I]], align 4 +; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i32 [[X_I_0_X_I_0_X_0_X_0_X_0__I]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP_I]] to i64 +; CHECK-NEXT: [[MUL_I2:%.*]] = mul i64 [[TMP0]], 4294967295 +; CHECK-NEXT: [[MUL_I1:%.*]] = trunc i64 [[MUL_I2]] to i32 +; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X_I]]) +; CHECK-NEXT: ret i32 [[MUL_I1]] +; +entry: + %x.i = alloca i32, align 4 + call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x.i) + store volatile i32 1, ptr %x.i, align 4 + %x.i.0.x.i.0.x.0.x.0.x.0..i = load volatile i32, ptr %x.i, align 4 + %cmp.i = icmp sgt i32 %x.i.0.x.i.0.x.0.x.0.x.0..i, 0 + %conv.i = uitofp i1 %cmp.i to double + %mul.i = fmul double %conv.i, 4294967295.0 + %conv1.i = fptoui double %mul.i to i32 + call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x.i) + ret i32 %conv1.i +} + +define i32 @pr79158_2() { +; CHECK-LABEL: @pr79158_2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X_I:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X_I]]) +; CHECK-NEXT: store volatile i32 1, ptr [[X_I]], align 4 +; CHECK-NEXT: [[X_I_0_X_I_0_X_0_X_0_X_0__I:%.*]] = load volatile i32, ptr [[X_I]], align 4 +; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i32 [[X_I_0_X_I_0_X_0_X_0_X_0__I]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP_I]] to i64 +; CHECK-NEXT: [[MUL_I2:%.*]] = mul i64 [[TMP0]], 2147483648 +; CHECK-NEXT: [[MUL_I1:%.*]] = trunc i64 [[MUL_I2]] to i32 +; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X_I]]) +; CHECK-NEXT: ret i32 [[MUL_I1]] +; +entry: + %x.i = alloca i32, align 4 + call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x.i) + store volatile i32 1, ptr %x.i, align 4 + %x.i.0.x.i.0.x.0.x.0.x.0..i = load volatile i32, ptr %x.i, align 4 + %cmp.i = icmp sgt i32 %x.i.0.x.i.0.x.0.x.0.x.0..i, 0 + %conv.i = uitofp i1 %cmp.i to double + %mul.i = fmul double %conv.i, 2147483648.0 + %conv1.i = fptoui double %mul.i to i32 + call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x.i) + ret i32 %conv1.i +}