Skip to content

Commit 8bd91ab

Browse files
committed
[Float2Int] Fix miscompile with floats that can be converted to large values
There is an issue with Float2Int whenever it has to deal with floats that evaluate to numbers that are over INT_MAX, but under UINT_MAX. Simply, because the conversion method always assumes a signed integer, this works until the 32 bit number is actually a positive 32 bit number that would be interpreted as a negative number when evaluated as an integer, being put in an i32. This was messing up the Float2Int conversions and causing miscompiles. To fix this, tell the APSInt constructor if the value is positive or negative.
1 parent 7198019 commit 8bd91ab

File tree

2 files changed

+5
-6
lines changed

2 files changed

+5
-6
lines changed

llvm/lib/Transforms/Scalar/Float2Int.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,10 @@ Value *Float2IntPass::convert(Instruction *I, Type *ToTy) {
407407
} else if (Instruction *VI = dyn_cast<Instruction>(V)) {
408408
NewOperands.push_back(convert(VI, ToTy));
409409
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
410-
APSInt Val(ToTy->getPrimitiveSizeInBits(), /*isUnsigned=*/false);
410+
const APFloat &F = CF->getValueAPF();
411+
APSInt Val(ToTy->getPrimitiveSizeInBits(), !F.isNegative());
411412
bool Exact;
412-
CF->getValueAPF().convertToInteger(Val,
413-
APFloat::rmNearestTiesToEven,
414-
&Exact);
413+
F.convertToInteger(Val, APFloat::rmNearestTiesToEven, &Exact);
415414
NewOperands.push_back(ConstantInt::get(ToTy, Val));
416415
} else {
417416
llvm_unreachable("Unhandled operand type?");

llvm/test/Transforms/Float2Int/basic.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ define i32 @pr79158() {
359359
; CHECK-NEXT: [[X_I_0_X_I_0_X_0_X_0_X_0__I:%.*]] = load volatile i32, ptr [[X_I]], align 4
360360
; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i32 [[X_I_0_X_I_0_X_0_X_0_X_0__I]], 0
361361
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP_I]] to i32
362-
; CHECK-NEXT: [[MUL_I1:%.*]] = mul i32 [[TMP0]], 2147483647
362+
; CHECK-NEXT: [[MUL_I1:%.*]] = mul i32 [[TMP0]], -1
363363
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X_I]])
364364
; CHECK-NEXT: ret i32 [[MUL_I1]]
365365
;
@@ -385,7 +385,7 @@ define i32 @pr79158_2() {
385385
; CHECK-NEXT: [[X_I_0_X_I_0_X_0_X_0_X_0__I:%.*]] = load volatile i32, ptr [[X_I]], align 4
386386
; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i32 [[X_I_0_X_I_0_X_0_X_0_X_0__I]], 0
387387
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP_I]] to i32
388-
; CHECK-NEXT: [[MUL_I1:%.*]] = mul i32 [[TMP0]], 2147483647
388+
; CHECK-NEXT: [[MUL_I1:%.*]] = mul i32 [[TMP0]], -2147483648
389389
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X_I]])
390390
; CHECK-NEXT: ret i32 [[MUL_I1]]
391391
;

0 commit comments

Comments
 (0)