Skip to content

Commit 6d5203d

Browse files
Merge pull request #8452 from AtariDreams/miscompile2
[ConstantRange] Fix miscompile caused by off by 1 bugs in UIToFP and SIToFP handling
2 parents 4de562f + ac0ae7c commit 6d5203d

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

llvm/lib/IR/ConstantRange.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
742742
Min = Min.zext(ResultBitWidth);
743743
Max = Max.zext(ResultBitWidth);
744744
}
745-
return ConstantRange(std::move(Min), std::move(Max));
745+
return getNonEmpty(std::move(Min), std::move(Max) + 1);
746746
}
747747
case Instruction::SIToFP: {
748748
// TODO: use input range if available
@@ -753,7 +753,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
753753
SMin = SMin.sext(ResultBitWidth);
754754
SMax = SMax.sext(ResultBitWidth);
755755
}
756-
return ConstantRange(std::move(SMin), std::move(SMax));
756+
return getNonEmpty(std::move(SMin), std::move(SMax) + 1);
757757
}
758758
case Instruction::FPTrunc:
759759
case Instruction::FPExt:
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -passes=float2int -S | FileCheck %s
3+
4+
define i32 @pr79158(i32 %x) {
5+
; CHECK-LABEL: define i32 @pr79158(
6+
; CHECK-SAME: i32 [[X:%.*]]) {
7+
; CHECK-NEXT: entry:
8+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 0
9+
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP]] to i64
10+
; CHECK-NEXT: [[MUL1:%.*]] = mul i64 [[TMP0]], 4294967295
11+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[MUL1]] to i32
12+
; CHECK-NEXT: ret i32 [[TMP1]]
13+
;
14+
entry:
15+
%cmp = icmp sgt i32 %x, 0
16+
%conv = uitofp i1 %cmp to double
17+
%mul = fmul double %conv, 0x41EFFFFFFFE00000
18+
%conv1 = fptoui double %mul to i32
19+
ret i32 %conv1
20+
}

llvm/unittests/IR/ConstantRangeTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,24 @@ TEST_F(ConstantRangeTest, castOps) {
24522452
ConstantRange IntToPtr = A.castOp(Instruction::IntToPtr, 64);
24532453
EXPECT_EQ(64u, IntToPtr.getBitWidth());
24542454
EXPECT_TRUE(IntToPtr.isFullSet());
2455+
2456+
ConstantRange UIToFP = A.castOp(Instruction::UIToFP, 16);
2457+
EXPECT_EQ(16u, UIToFP.getBitWidth());
2458+
EXPECT_TRUE(UIToFP.isFullSet());
2459+
2460+
ConstantRange UIToFP2 = A.castOp(Instruction::UIToFP, 64);
2461+
ConstantRange B(APInt(64, 0), APInt(64, 65536));
2462+
EXPECT_EQ(64u, UIToFP2.getBitWidth());
2463+
EXPECT_EQ(B, UIToFP2);
2464+
2465+
ConstantRange SIToFP = A.castOp(Instruction::SIToFP, 16);
2466+
EXPECT_EQ(16u, SIToFP.getBitWidth());
2467+
EXPECT_TRUE(SIToFP.isFullSet());
2468+
2469+
ConstantRange SIToFP2 = A.castOp(Instruction::SIToFP, 64);
2470+
ConstantRange C(APInt(64, -32768), APInt(64, 32768));
2471+
EXPECT_EQ(64u, SIToFP2.getBitWidth());
2472+
EXPECT_EQ(C, SIToFP2);
24552473
}
24562474

24572475
TEST_F(ConstantRangeTest, binaryAnd) {

0 commit comments

Comments
 (0)