aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/IR/ConstantRangeTest.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-08-02 00:03:44 +0800
committerGitHub <noreply@github.com>2024-08-02 00:03:44 +0800
commit1a5d8926c5f9c1e75a285e122cf6cad0191a41b5 (patch)
tree2e7b2381bd333c5695174970c86f84b0d206dfea /llvm/unittests/IR/ConstantRangeTest.cpp
parentb5fc083dc30994f8d4f43ba6064d7b27467352c0 (diff)
downloadllvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.zip
llvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.tar.gz
llvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.tar.bz2
[ConstantRange] Add support for `shlWithNoWrap` (#100594)
This patch adds initial support for `ConstantRange:: shlWithNoWrap` to fold https://github.com/dtcxzyw/llvm-tools/issues/22. However, this patch cannot fix the original issue. Improvements will be submitted in subsequent patches.
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r--llvm/unittests/IR/ConstantRangeTest.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp
index 7977a78..1705f3e 100644
--- a/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -1502,6 +1502,48 @@ TEST_F(ConstantRangeTest, Shl) {
});
}
+TEST_F(ConstantRangeTest, ShlWithNoWrap) {
+ using OBO = OverflowingBinaryOperator;
+ TestBinaryOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.shlWithNoWrap(CR2, OBO::NoUnsignedWrap);
+ },
+ [](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
+ bool IsOverflow;
+ APInt Res = N1.ushl_ov(N2, IsOverflow);
+ if (IsOverflow)
+ return std::nullopt;
+ return Res;
+ },
+ PreferSmallest, CheckCorrectnessOnly);
+ TestBinaryOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.shlWithNoWrap(CR2, OBO::NoSignedWrap);
+ },
+ [](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
+ bool IsOverflow;
+ APInt Res = N1.sshl_ov(N2, IsOverflow);
+ if (IsOverflow)
+ return std::nullopt;
+ return Res;
+ },
+ PreferSmallest, CheckCorrectnessOnly);
+ TestBinaryOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.shlWithNoWrap(CR2, OBO::NoUnsignedWrap | OBO::NoSignedWrap);
+ },
+ [](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
+ bool IsOverflow1, IsOverflow2;
+ APInt Res1 = N1.ushl_ov(N2, IsOverflow1);
+ APInt Res2 = N1.sshl_ov(N2, IsOverflow2);
+ if (IsOverflow1 || IsOverflow2)
+ return std::nullopt;
+ assert(Res1 == Res2 && "Left shift results differ?");
+ return Res1;
+ },
+ PreferSmallest, CheckCorrectnessOnly);
+}
+
TEST_F(ConstantRangeTest, Lshr) {
EXPECT_EQ(Full.lshr(Full), Full);
EXPECT_EQ(Full.lshr(Empty), Empty);