diff options
| author | Atousa Duprat <atousa.p@gmail.com> | 2024-03-14 03:00:08 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-14 10:00:08 +0000 | 
| commit | aff05708916107eec73ea5db363f625926f60730 (patch) | |
| tree | 497984210c19d7eb639f360e20fefd9c27972603 /llvm/unittests/ADT/APIntTest.cpp | |
| parent | afec257d369a13893b39d02bc630f9f3cec80162 (diff) | |
| download | llvm-aff05708916107eec73ea5db363f625926f60730.zip llvm-aff05708916107eec73ea5db363f625926f60730.tar.gz llvm-aff05708916107eec73ea5db363f625926f60730.tar.bz2 | |
[ADT] Add implementations for avgFloor and avgCeil to APInt (#84431)
Supports both signed and unsigned expansions.
SelectionDAG now calls the APInt implementation of these functions.
Fixes #84211.
Diffstat (limited to 'llvm/unittests/ADT/APIntTest.cpp')
| -rw-r--r-- | llvm/unittests/ADT/APIntTest.cpp | 86 | 
1 files changed, 86 insertions, 0 deletions
| diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 11237d2..400313a 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -14,6 +14,7 @@  #include "llvm/Support/Alignment.h"  #include "gtest/gtest.h"  #include <array> +#include <climits>  #include <optional>  using namespace llvm; @@ -2911,6 +2912,91 @@ TEST(APIntTest, RoundingSDiv) {    }  } +TEST(APIntTest, Average) { +  APInt A0(32, 0); +  APInt A2(32, 2); +  APInt A100(32, 100); +  APInt A101(32, 101); +  APInt A200(32, 200, false); +  APInt ApUMax(32, UINT_MAX, false); + +  EXPECT_EQ(APInt(32, 150), APIntOps::avgFloorU(A100, A200)); +  EXPECT_EQ(APIntOps::RoundingUDiv(A100 + A200, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorU(A100, A200)); +  EXPECT_EQ(APIntOps::RoundingUDiv(A100 + A200, A2, APInt::Rounding::UP), +            APIntOps::avgCeilU(A100, A200)); +  EXPECT_EQ(APIntOps::RoundingUDiv(A100 + A101, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorU(A100, A101)); +  EXPECT_EQ(APIntOps::RoundingUDiv(A100 + A101, A2, APInt::Rounding::UP), +            APIntOps::avgCeilU(A100, A101)); +  EXPECT_EQ(A0, APIntOps::avgFloorU(A0, A0)); +  EXPECT_EQ(A0, APIntOps::avgCeilU(A0, A0)); +  EXPECT_EQ(ApUMax, APIntOps::avgFloorU(ApUMax, ApUMax)); +  EXPECT_EQ(ApUMax, APIntOps::avgCeilU(ApUMax, ApUMax)); +  EXPECT_EQ(APIntOps::RoundingUDiv(ApUMax, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorU(A0, ApUMax)); +  EXPECT_EQ(APIntOps::RoundingUDiv(ApUMax, A2, APInt::Rounding::UP), +            APIntOps::avgCeilU(A0, ApUMax)); + +  APInt Ap100(32, +100); +  APInt Ap101(32, +101); +  APInt Ap200(32, +200); +  APInt Am1(32, -1); +  APInt Am100(32, -100); +  APInt Am101(32, -101); +  APInt Am200(32, -200); +  APInt AmSMin(32, INT_MIN); +  APInt ApSMax(32, INT_MAX); + +  EXPECT_EQ(APInt(32, +150), APIntOps::avgFloorS(Ap100, Ap200)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap200, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(Ap100, Ap200)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap200, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(Ap100, Ap200)); + +  EXPECT_EQ(APInt(32, -150), APIntOps::avgFloorS(Am100, Am200)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am200, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(Am100, Am200)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am200, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(Am100, Am200)); + +  EXPECT_EQ(APInt(32, +100), APIntOps::avgFloorS(Ap100, Ap101)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap101, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(Ap100, Ap101)); +  EXPECT_EQ(APInt(32, +101), APIntOps::avgCeilS(Ap100, Ap101)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Ap100 + Ap101, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(Ap100, Ap101)); + +  EXPECT_EQ(APInt(32, -101), APIntOps::avgFloorS(Am100, Am101)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am101, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(Am100, Am101)); +  EXPECT_EQ(APInt(32, -100), APIntOps::avgCeilS(Am100, Am101)); +  EXPECT_EQ(APIntOps::RoundingSDiv(Am100 + Am101, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(Am100, Am101)); + +  EXPECT_EQ(AmSMin, APIntOps::avgFloorS(AmSMin, AmSMin)); +  EXPECT_EQ(AmSMin, APIntOps::avgCeilS(AmSMin, AmSMin)); + +  EXPECT_EQ(APIntOps::RoundingSDiv(AmSMin, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(A0, AmSMin)); +  EXPECT_EQ(APIntOps::RoundingSDiv(AmSMin, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(A0, AmSMin)); + +  EXPECT_EQ(A0, APIntOps::avgFloorS(A0, A0)); +  EXPECT_EQ(A0, APIntOps::avgCeilS(A0, A0)); + +  EXPECT_EQ(Am1, APIntOps::avgFloorS(AmSMin, ApSMax)); +  EXPECT_EQ(A0, APIntOps::avgCeilS(AmSMin, ApSMax)); + +  EXPECT_EQ(APIntOps::RoundingSDiv(ApSMax, A2, APInt::Rounding::DOWN), +            APIntOps::avgFloorS(A0, ApSMax)); +  EXPECT_EQ(APIntOps::RoundingSDiv(ApSMax, A2, APInt::Rounding::UP), +            APIntOps::avgCeilS(A0, ApSMax)); + +  EXPECT_EQ(ApSMax, APIntOps::avgFloorS(ApSMax, ApSMax)); +  EXPECT_EQ(ApSMax, APIntOps::avgCeilS(ApSMax, ApSMax)); +} +  TEST(APIntTest, umul_ov) {    const std::pair<uint64_t, uint64_t> Overflows[] = {        {0x8000000000000000, 2}, | 
