Skip to content

Commit feba872

Browse files
topperctstellar
authored andcommitted
[ConstantRange] Fix off by 1 bugs in UIToFP and SIToFP handling. (llvm#86041)
We were passing the min and max values of the range to the ConstantRange constructor, but the constructor expects the upper bound to 1 more than the max value so we need to add 1. We also need to use getNonEmpty so that passing 0, 0 to the constructor creates a full range rather than an empty range. And passing smin, smax+1 doesn't cause an assertion. I believe this fixes at least some of the reason llvm#79158 was reverted. (cherry picked from commit 1283646)
1 parent e4259b5 commit feba872

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

llvm/lib/IR/ConstantRange.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
746746
Min = Min.zext(ResultBitWidth);
747747
Max = Max.zext(ResultBitWidth);
748748
}
749-
return ConstantRange(std::move(Min), std::move(Max));
749+
return getNonEmpty(std::move(Min), std::move(Max) + 1);
750750
}
751751
case Instruction::SIToFP: {
752752
// TODO: use input range if available
@@ -757,7 +757,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
757757
SMin = SMin.sext(ResultBitWidth);
758758
SMax = SMax.sext(ResultBitWidth);
759759
}
760-
return ConstantRange(std::move(SMin), std::move(SMax));
760+
return getNonEmpty(std::move(SMin), std::move(SMax) + 1);
761761
}
762762
case Instruction::FPTrunc:
763763
case Instruction::FPExt:

llvm/test/Transforms/Float2Int/pr79158.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ define i32 @pr79158(i32 %x) {
66
; CHECK-SAME: i32 [[X:%.*]]) {
77
; CHECK-NEXT: entry:
88
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 0
9-
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP]] to i32
10-
; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP0]], 2147483647
11-
; CHECK-NEXT: ret i32 [[MUL1]]
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]]
1213
;
1314
entry:
1415
%cmp = icmp sgt i32 %x, 0

llvm/unittests/IR/ConstantRangeTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,24 @@ TEST_F(ConstantRangeTest, castOps) {
24792479
ConstantRange IntToPtr = A.castOp(Instruction::IntToPtr, 64);
24802480
EXPECT_EQ(64u, IntToPtr.getBitWidth());
24812481
EXPECT_TRUE(IntToPtr.isFullSet());
2482+
2483+
ConstantRange UIToFP = A.castOp(Instruction::UIToFP, 16);
2484+
EXPECT_EQ(16u, UIToFP.getBitWidth());
2485+
EXPECT_TRUE(UIToFP.isFullSet());
2486+
2487+
ConstantRange UIToFP2 = A.castOp(Instruction::UIToFP, 64);
2488+
ConstantRange B(APInt(64, 0), APInt(64, 65536));
2489+
EXPECT_EQ(64u, UIToFP2.getBitWidth());
2490+
EXPECT_EQ(B, UIToFP2);
2491+
2492+
ConstantRange SIToFP = A.castOp(Instruction::SIToFP, 16);
2493+
EXPECT_EQ(16u, SIToFP.getBitWidth());
2494+
EXPECT_TRUE(SIToFP.isFullSet());
2495+
2496+
ConstantRange SIToFP2 = A.castOp(Instruction::SIToFP, 64);
2497+
ConstantRange C(APInt(64, -32768), APInt(64, 32768));
2498+
EXPECT_EQ(64u, SIToFP2.getBitWidth());
2499+
EXPECT_EQ(C, SIToFP2);
24822500
}
24832501

24842502
TEST_F(ConstantRangeTest, binaryAnd) {

0 commit comments

Comments
 (0)