diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-08-02 00:03:44 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 00:03:44 +0800 |
commit | 1a5d8926c5f9c1e75a285e122cf6cad0191a41b5 (patch) | |
tree | 2e7b2381bd333c5695174970c86f84b0d206dfea /llvm/unittests/IR/ConstantRangeTest.cpp | |
parent | b5fc083dc30994f8d4f43ba6064d7b27467352c0 (diff) | |
download | llvm-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.cpp | 42 |
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); |