Index: include/polly/Support/GICHelper.h =================================================================== --- include/polly/Support/GICHelper.h +++ include/polly/Support/GICHelper.h @@ -37,6 +37,36 @@ } // 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); Index: lib/Support/GICHelper.cpp =================================================================== --- lib/Support/GICHelper.cpp +++ lib/Support/GICHelper.cpp @@ -30,8 +30,19 @@ 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; Index: unittests/Isl/IslTest.cpp =================================================================== --- unittests/Isl/IslTest.cpp +++ unittests/Isl/IslTest.cpp @@ -20,6 +20,43 @@ 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_val_eq(IslNTwo, IslNTwoCmp), isl_bool_true); + 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)); @@ -56,6 +93,17 @@ 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_val_eq(IslLarge, IslRef), isl_bool_true); + isl_val_free(IslLarge); + isl_val_free(IslRef); + } + isl_ctx_free(IslCtx); }