summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/Support/GICHelper.h30
-rw-r--r--polly/lib/Support/GICHelper.cpp13
-rw-r--r--polly/unittests/Isl/IslTest.cpp56
3 files changed, 94 insertions, 5 deletions
diff --git a/polly/include/polly/Support/GICHelper.h b/polly/include/polly/Support/GICHelper.h
index 4686b6c51cf..e4861eb9b0b 100644
--- a/polly/include/polly/Support/GICHelper.h
+++ b/polly/include/polly/Support/GICHelper.h
@@ -37,6 +37,36 @@ class Value;
} // namespace llvm
namespace polly {
+
+/// @brief Translate an llvm::APInt to an isl_val.
+///
+/// Translate the bitsequence without sign information as provided by APInt into
+/// a signed isl_val type. Depending on the value of @p IsSigned @p Int is
+/// interpreted as unsigned value or as signed value in two's complement
+/// representation.
+///
+/// Input IsSigned Output
+///
+/// 0 0 -> 0
+/// 1 0 -> 1
+/// 00 0 -> 0
+/// 01 0 -> 1
+/// 10 0 -> 2
+/// 11 0 -> 3
+///
+/// 0 1 -> 0
+/// 1 1 -> -1
+/// 00 1 -> 0
+/// 01 1 -> 1
+/// 10 1 -> -2
+/// 11 1 -> -1
+///
+/// @param Ctx The isl_ctx to create the isl_val in.
+/// @param Int The integer value to translate.
+/// @param IsSigned If the APInt should be interpreted as signed or unsigned
+/// value.
+///
+/// @return The isl_val corresponding to @p Int.
__isl_give isl_val *isl_valFromAPInt(isl_ctx *Ctx, const llvm::APInt Int,
bool IsSigned);
diff --git a/polly/lib/Support/GICHelper.cpp b/polly/lib/Support/GICHelper.cpp
index 48b601334d1..e3a59993aec 100644
--- a/polly/lib/Support/GICHelper.cpp
+++ b/polly/lib/Support/GICHelper.cpp
@@ -30,8 +30,19 @@ __isl_give isl_val *polly::isl_valFromAPInt(isl_ctx *Ctx, const APInt Int,
APInt Abs;
isl_val *v;
+ // As isl is interpreting the input always as unsigned value, we need some
+ // additional pre and post processing to import signed values. The approach
+ // we take is to first obtain the absolute value of Int and then negate the
+ // value after it has been imported to isl.
+ //
+ // It should be noted that the smallest integer value represented in two's
+ // complement with a certain amount of bits does not have a corresponding
+ // positive representation in two's complement representation with the same
+ // number of bits. E.g. 110 (-2) does not have a corresponding value for (2).
+ // To ensure that there is always a corresponding value available we first
+ // sign-extend the input by one bit and only then take the absolute value.
if (IsSigned)
- Abs = Int.abs();
+ Abs = Int.sext(Int.getBitWidth() + 1).abs();
else
Abs = Int;
diff --git a/polly/unittests/Isl/IslTest.cpp b/polly/unittests/Isl/IslTest.cpp
index 6b3fc03c96b..5dccaba051c 100644
--- a/polly/unittests/Isl/IslTest.cpp
+++ b/polly/unittests/Isl/IslTest.cpp
@@ -20,6 +20,43 @@ TEST(Isl, APIntToIslVal) {
isl_ctx *IslCtx = isl_ctx_alloc();
{
+ APInt APZero(1, 0, true);
+ auto *IslZero = isl_valFromAPInt(IslCtx, APZero, true);
+ EXPECT_EQ(isl_bool_true, isl_val_is_zero(IslZero));
+ isl_val_free(IslZero);
+ }
+
+ {
+ APInt APNOne(1, -1, true);
+ auto *IslNOne = isl_valFromAPInt(IslCtx, APNOne, true);
+ EXPECT_EQ(isl_bool_true, isl_val_is_negone(IslNOne));
+ isl_val_free(IslNOne);
+ }
+
+ {
+ APInt APZero(1, 0, false);
+ auto *IslZero = isl_valFromAPInt(IslCtx, APZero, false);
+ EXPECT_EQ(isl_bool_true, isl_val_is_zero(IslZero));
+ isl_val_free(IslZero);
+ }
+
+ {
+ APInt APOne(1, 1, false);
+ auto *IslOne = isl_valFromAPInt(IslCtx, APOne, false);
+ EXPECT_EQ(isl_bool_true, isl_val_is_one(IslOne));
+ isl_val_free(IslOne);
+ }
+
+ {
+ APInt APNTwo(2, -2, true);
+ auto *IslNTwo = isl_valFromAPInt(IslCtx, APNTwo, true);
+ auto *IslNTwoCmp = isl_val_int_from_si(IslCtx, -2);
+ EXPECT_EQ(isl_bool_true, isl_val_eq(IslNTwo, IslNTwoCmp));
+ isl_val_free(IslNTwo);
+ isl_val_free(IslNTwoCmp);
+ }
+
+ {
APInt APNOne(32, -1, true);
auto *IslNOne = isl_valFromAPInt(IslCtx, APNOne, true);
EXPECT_EQ(isl_bool_true, isl_val_is_negone(IslNOne));
@@ -29,21 +66,21 @@ TEST(Isl, APIntToIslVal) {
{
APInt APZero(32, 0, false);
auto *IslZero = isl_valFromAPInt(IslCtx, APZero, false);
- EXPECT_EQ(isl_val_is_zero(IslZero), isl_bool_true);
+ EXPECT_EQ(isl_bool_true, isl_val_is_zero(IslZero));
isl_val_free(IslZero);
}
{
APInt APOne(32, 1, false);
auto *IslOne = isl_valFromAPInt(IslCtx, APOne, false);
- EXPECT_EQ(isl_val_is_one(IslOne), isl_bool_true);
+ EXPECT_EQ(isl_bool_true, isl_val_is_one(IslOne));
isl_val_free(IslOne);
}
{
APInt APTwo(32, 2, false);
auto *IslTwo = isl_valFromAPInt(IslCtx, APTwo, false);
- EXPECT_EQ(isl_val_cmp_si(IslTwo, 2), 0);
+ EXPECT_EQ(0, isl_val_cmp_si(IslTwo, 2));
isl_val_free(IslTwo);
}
@@ -51,11 +88,22 @@ TEST(Isl, APIntToIslVal) {
APInt APNOne(32, (1ull << 32) - 1, false);
auto *IslNOne = isl_valFromAPInt(IslCtx, APNOne, false);
auto *IslRef = isl_val_int_from_ui(IslCtx, (1ull << 32) - 1);
- EXPECT_EQ(isl_val_eq(IslNOne, IslRef), isl_bool_true);
+ EXPECT_EQ(isl_bool_true, isl_val_eq(IslNOne, IslRef));
isl_val_free(IslNOne);
isl_val_free(IslRef);
}
+ {
+ APInt APLarge(130, 2, false);
+ APLarge = APLarge.shl(70);
+ auto *IslLarge = isl_valFromAPInt(IslCtx, APLarge, false);
+ auto *IslRef = isl_val_int_from_ui(IslCtx, 71);
+ IslRef = isl_val_2exp(IslRef);
+ EXPECT_EQ(isl_bool_true, isl_val_eq(IslLarge, IslRef));
+ isl_val_free(IslLarge);
+ isl_val_free(IslRef);
+ }
+
isl_ctx_free(IslCtx);
}
OpenPOWER on IntegriCloud