aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ADT/APIntTest.cpp
diff options
context:
space:
mode:
authorAtousa Duprat <atousa.p@gmail.com>2024-03-14 03:00:08 -0700
committerGitHub <noreply@github.com>2024-03-14 10:00:08 +0000
commitaff05708916107eec73ea5db363f625926f60730 (patch)
tree497984210c19d7eb639f360e20fefd9c27972603 /llvm/unittests/ADT/APIntTest.cpp
parentafec257d369a13893b39d02bc630f9f3cec80162 (diff)
downloadllvm-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.cpp86
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},