https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/86153
Backport 6295e677220bb6ec1fa8abe2f4a94b513b91b786 12836467b76c56872b4c22a6fd44bcda696ea720 Requested by: @AtariDreams >From b7d167a678570b64accc5055823c339a07b72d60 Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.top...@sifive.com> Date: Wed, 20 Mar 2024 17:05:17 -0700 Subject: [PATCH 1/2] [Float2Int] Pre-commit test for SIToFP/UIToFP ConstantRange bug. NFC The range for these operations is being constructed without the maximum value for the range due to an incorrect usage of the ConstantRange constructor. This causes Float2Int to think the range for 'uitofp i1' only contains 0 instead of 0 and 1. (cherry picked from commit 6295e677220bb6ec1fa8abe2f4a94b513b91b786) --- llvm/test/Transforms/Float2Int/pr79158.ll | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 llvm/test/Transforms/Float2Int/pr79158.ll diff --git a/llvm/test/Transforms/Float2Int/pr79158.ll b/llvm/test/Transforms/Float2Int/pr79158.ll new file mode 100644 index 00000000000000..d041e01a4b5997 --- /dev/null +++ b/llvm/test/Transforms/Float2Int/pr79158.ll @@ -0,0 +1,19 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt < %s -passes=float2int -S | FileCheck %s + +define i32 @pr79158(i32 %x) { +; CHECK-LABEL: define i32 @pr79158( +; 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]] +; +entry: + %cmp = icmp sgt i32 %x, 0 + %conv = uitofp i1 %cmp to double + %mul = fmul double %conv, 0x41EFFFFFFFE00000 + %conv1 = fptoui double %mul to i32 + ret i32 %conv1 +} >From 613a8ae95b03dfec69e3cca597bbfacfa7f92724 Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.top...@sifive.com> Date: Thu, 21 Mar 2024 09:25:13 -0700 Subject: [PATCH 2/2] [ConstantRange] Fix off by 1 bugs in UIToFP and SIToFP handling. (#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 #79158 was reverted. (cherry picked from commit 12836467b76c56872b4c22a6fd44bcda696ea720) --- llvm/lib/IR/ConstantRange.cpp | 4 ++-- llvm/test/Transforms/Float2Int/pr79158.ll | 7 ++++--- llvm/unittests/IR/ConstantRangeTest.cpp | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index cbb64b299e648e..f105bdb4816aa0 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -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 @@ -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: diff --git a/llvm/test/Transforms/Float2Int/pr79158.ll b/llvm/test/Transforms/Float2Int/pr79158.ll index d041e01a4b5997..5e78cc0bc66fdb 100644 --- a/llvm/test/Transforms/Float2Int/pr79158.ll +++ b/llvm/test/Transforms/Float2Int/pr79158.ll @@ -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 diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index e505af5d3275ef..f60bb4c135bec3 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -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) { _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits