Skip to content

Commit

Permalink
[ConstantRange] Fix off by 1 bugs in UIToFP and SIToFP handling. (llv…
Browse files Browse the repository at this point in the history
…m#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.
  • Loading branch information
topperc authored and chencha3 committed Mar 22, 2024
1 parent db61018 commit e944991
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
4 changes: 2 additions & 2 deletions llvm/lib/IR/ConstantRange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
Min = Min.zext(ResultBitWidth);
Max = Max.zext(ResultBitWidth);
}
return ConstantRange(std::move(Min), std::move(Max));
return getNonEmpty(std::move(Min), std::move(Max) + 1);
}
case Instruction::SIToFP: {
// TODO: use input range if available
Expand All @@ -757,7 +757,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
SMin = SMin.sext(ResultBitWidth);
SMax = SMax.sext(ResultBitWidth);
}
return ConstantRange(std::move(SMin), std::move(SMax));
return getNonEmpty(std::move(SMin), std::move(SMax) + 1);
}
case Instruction::FPTrunc:
case Instruction::FPExt:
Expand Down
7 changes: 4 additions & 3 deletions llvm/test/Transforms/Float2Int/pr79158.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ define i32 @pr79158(i32 %x) {
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 0
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP0]], 2147483647
; CHECK-NEXT: ret i32 [[MUL1]]
; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CMP]] to i64
; CHECK-NEXT: [[MUL1:%.*]] = mul i64 [[TMP0]], 4294967295
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[MUL1]] to i32
; CHECK-NEXT: ret i32 [[TMP1]]
;
entry:
%cmp = icmp sgt i32 %x, 0
Expand Down
18 changes: 18 additions & 0 deletions llvm/unittests/IR/ConstantRangeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2479,6 +2479,24 @@ TEST_F(ConstantRangeTest, castOps) {
ConstantRange IntToPtr = A.castOp(Instruction::IntToPtr, 64);
EXPECT_EQ(64u, IntToPtr.getBitWidth());
EXPECT_TRUE(IntToPtr.isFullSet());

ConstantRange UIToFP = A.castOp(Instruction::UIToFP, 16);
EXPECT_EQ(16u, UIToFP.getBitWidth());
EXPECT_TRUE(UIToFP.isFullSet());

ConstantRange UIToFP2 = A.castOp(Instruction::UIToFP, 64);
ConstantRange B(APInt(64, 0), APInt(64, 65536));
EXPECT_EQ(64u, UIToFP2.getBitWidth());
EXPECT_EQ(B, UIToFP2);

ConstantRange SIToFP = A.castOp(Instruction::SIToFP, 16);
EXPECT_EQ(16u, SIToFP.getBitWidth());
EXPECT_TRUE(SIToFP.isFullSet());

ConstantRange SIToFP2 = A.castOp(Instruction::SIToFP, 64);
ConstantRange C(APInt(64, -32768), APInt(64, 32768));
EXPECT_EQ(64u, SIToFP2.getBitWidth());
EXPECT_EQ(C, SIToFP2);
}

TEST_F(ConstantRangeTest, binaryAnd) {
Expand Down

0 comments on commit e944991

Please sign in to comment.