-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Fix MASKR/MASKL lowering for INTEGER(16) #87496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The all one masks was not properly created for i128 types because builder.createIntegerConstant ended-up truncating -1 to something positive. Add a builder.createAllOnesInteger helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried using bbc with this change for tests that exercise kind=10 and kind=16? It's not mandatory, but it's nice to keep bbc as usuable as possible. (The lit tests may or may not already do that depending on the types involved.)
The ieee_class was actually relying on createIntegerConstant to zero extend "-1" from 64 to 128 bits. Use APInt instead to build the masks, this allows simplifying the code. use APInt
@llvm/pr-subscribers-flang-fir-hlfir Author: None (jeanPerier) ChangesThe all one masks was not properly created for i128 types because builder.createIntegerConstant ended-up truncating -1 to something positive. Add a builder.createAllOnesInteger/createMinusOneInteger helpers and use them where createIntegerConstant(..., -1) was used. Patch is 26.16 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87496.diff 8 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 940866b25d2fe8..e4c954159f71be 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -164,9 +164,22 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
mlir::Value createNullConstant(mlir::Location loc, mlir::Type ptrType = {});
/// Create an integer constant of type \p type and value \p i.
+ /// Should not be used with negative values with integer types of more
+ /// than 64 bits.
mlir::Value createIntegerConstant(mlir::Location loc, mlir::Type integerType,
std::int64_t i);
+ /// Create an integer of \p integerType where all the bits have been set to
+ /// ones. Safe to use regardless of integerType bitwidth.
+ mlir::Value createAllOnesInteger(mlir::Location loc, mlir::Type integerType);
+
+ /// Create -1 constant of \p integerType. Safe to use regardless of
+ /// integerType bitwidth.
+ mlir::Value createMinusOneInteger(mlir::Location loc,
+ mlir::Type integerType) {
+ return createAllOnesInteger(loc, integerType);
+ }
+
/// Create a real constant from an integer value.
mlir::Value createRealConstant(mlir::Location loc, mlir::Type realType,
llvm::APFloat::integerPart val);
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index e07ae42dc74973..5f53e0fd34fd71 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1462,7 +1462,7 @@ static void lowerExplicitLowerBounds(
/// CFI_desc_t requirements in 18.5.3 point 5.).
static mlir::Value getAssumedSizeExtent(mlir::Location loc,
fir::FirOpBuilder &builder) {
- return builder.createIntegerConstant(loc, builder.getIndexType(), -1);
+ return builder.createMinusOneInteger(loc, builder.getIndexType());
}
/// Lower explicit extents into \p result if this is an explicit-shape or
diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h
index 6daa72b84d90d4..3ebf3fd965da1e 100644
--- a/flang/lib/Lower/DirectivesCommon.h
+++ b/flang/lib/Lower/DirectivesCommon.h
@@ -744,7 +744,7 @@ genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc,
// Box is not present. Populate bound values with default values.
llvm::SmallVector<mlir::Value> boundValues;
mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
- mlir::Value mOne = builder.createIntegerConstant(loc, idxTy, -1);
+ mlir::Value mOne = builder.createMinusOneInteger(loc, idxTy);
for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
boundValues.push_back(zero); // lb
boundValues.push_back(mOne); // ub
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index e4362b2f9e6945..b09da4929a8a27 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -128,9 +128,21 @@ mlir::Value fir::FirOpBuilder::createNullConstant(mlir::Location loc,
mlir::Value fir::FirOpBuilder::createIntegerConstant(mlir::Location loc,
mlir::Type ty,
std::int64_t cst) {
+ assert((cst >= 0 || mlir::isa<mlir::IndexType>(ty) ||
+ mlir::cast<mlir::IntegerType>(ty).getWidth() <= 64) &&
+ "must use APint");
return create<mlir::arith::ConstantOp>(loc, ty, getIntegerAttr(ty, cst));
}
+mlir::Value fir::FirOpBuilder::createAllOnesInteger(mlir::Location loc,
+ mlir::Type ty) {
+ if (mlir::isa<mlir::IndexType>(ty))
+ return createIntegerConstant(loc, ty, -1);
+ llvm::APInt allOnes =
+ llvm::APInt::getAllOnes(mlir::cast<mlir::IntegerType>(ty).getWidth());
+ return create<mlir::arith::ConstantOp>(loc, ty, getIntegerAttr(ty, allOnes));
+}
+
mlir::Value
fir::FirOpBuilder::createRealConstant(mlir::Location loc, mlir::Type fltTy,
llvm::APFloat::integerPart val) {
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 069ba81cfe96ab..1c16eb83c58f47 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -3621,7 +3621,7 @@ mlir::Value IntrinsicLibrary::genIbclr(mlir::Type resultType,
assert(args.size() == 2);
mlir::Value pos = builder.createConvert(loc, resultType, args[1]);
mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
auto mask = builder.create<mlir::arith::ShLIOp>(loc, one, pos);
auto res = builder.create<mlir::arith::XOrIOp>(loc, ones, mask);
return builder.create<mlir::arith::AndIOp>(loc, args[0], res);
@@ -3645,7 +3645,7 @@ mlir::Value IntrinsicLibrary::genIbits(mlir::Type resultType,
loc, resultType, resultType.cast<mlir::IntegerType>().getWidth());
auto shiftCount = builder.create<mlir::arith::SubIOp>(loc, bitSize, len);
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
auto mask = builder.create<mlir::arith::ShRUIOp>(loc, ones, shiftCount);
auto res1 = builder.create<mlir::arith::ShRSIOp>(loc, args[0], pos);
auto res2 = builder.create<mlir::arith::AndIOp>(loc, res1, mask);
@@ -3805,7 +3805,8 @@ mlir::Value IntrinsicLibrary::genIeeeClass(mlir::Type resultType,
assert(args.size() == 1);
mlir::Value realVal = args[0];
mlir::FloatType realType = realVal.getType().dyn_cast<mlir::FloatType>();
- mlir::Type intType = builder.getIntegerType(realType.getWidth());
+ const unsigned intWidth = realType.getWidth();
+ mlir::Type intType = builder.getIntegerType(intWidth);
mlir::Value intVal =
builder.create<mlir::arith::BitcastOp>(loc, intType, realVal);
llvm::StringRef tableName = RTNAME_STRING(IeeeClassTable);
@@ -3816,41 +3817,25 @@ mlir::Value IntrinsicLibrary::genIeeeClass(mlir::Type resultType,
auto createIntegerConstant = [&](uint64_t k) {
return builder.createIntegerConstant(loc, intType, k);
};
+ auto createIntegerConstantAPI = [&](const llvm::APInt &apInt) {
+ return builder.create<mlir::arith::ConstantOp>(
+ loc, intType, builder.getIntegerAttr(intType, apInt));
+ };
auto getMasksAndShifts = [&](uint64_t totalSize, uint64_t exponentSize,
uint64_t significandSize,
bool hasExplicitBit = false) {
assert(1 + exponentSize + significandSize == totalSize &&
"invalid floating point fields");
- constexpr uint64_t one = 1; // type promotion
uint64_t lowSignificandSize = significandSize - hasExplicitBit - 1;
signShift = createIntegerConstant(totalSize - 1 - hasExplicitBit - 4);
highSignificandShift = createIntegerConstant(lowSignificandSize);
- if (totalSize <= 64) {
- exponentMask =
- createIntegerConstant(((one << exponentSize) - 1) << significandSize);
- lowSignificandMask =
- createIntegerConstant((one << lowSignificandSize) - 1);
- return;
- }
- // Mlir can't directly build large constants. Build them in steps.
- // The folded end result is the same.
- mlir::Value sixtyfour = createIntegerConstant(64);
- exponentMask = createIntegerConstant(((one << exponentSize) - 1)
- << (significandSize - 64));
- exponentMask =
- builder.create<mlir::arith::ShLIOp>(loc, exponentMask, sixtyfour);
- if (lowSignificandSize <= 64) {
- lowSignificandMask =
- createIntegerConstant((one << lowSignificandSize) - 1);
- return;
- }
- mlir::Value ones = createIntegerConstant(0xffffffffffffffff);
- lowSignificandMask =
- createIntegerConstant((one << (lowSignificandSize - 64)) - 1);
- lowSignificandMask =
- builder.create<mlir::arith::ShLIOp>(loc, lowSignificandMask, sixtyfour);
- lowSignificandMask =
- builder.create<mlir::arith::OrIOp>(loc, lowSignificandMask, ones);
+ llvm::APInt exponentMaskAPI =
+ llvm::APInt::getBitsSet(intWidth, /*lo=*/significandSize,
+ /*hi=*/significandSize + exponentSize);
+ exponentMask = createIntegerConstantAPI(exponentMaskAPI);
+ llvm::APInt lowSignificandMaskAPI =
+ llvm::APInt::getLowBitsSet(intWidth, lowSignificandSize);
+ lowSignificandMask = createIntegerConstantAPI(lowSignificandMaskAPI);
};
switch (realType.getWidth()) {
case 16:
@@ -4318,7 +4303,7 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
// X is zero -- result is -infinity
builder.setInsertionPointToStart(&outerIfOp.getThenRegion().front());
genRaiseExcept(_FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO);
- mlir::Value ones = builder.createIntegerConstant(loc, intType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, intType);
mlir::Value result = builder.create<mlir::arith::ShLIOp>(
loc, ones,
builder.createIntegerConstant(loc, intType,
@@ -4937,7 +4922,7 @@ mlir::Value IntrinsicLibrary::genIshftc(mlir::Type resultType,
mlir::Value size =
args[2] ? builder.createConvert(loc, resultType, args[2]) : bitSize;
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
mlir::Value absShift = genAbs(resultType, {shift});
auto elseSize = builder.create<mlir::arith::SubIOp>(loc, size, absShift);
auto shiftIsZero = builder.create<mlir::arith::CmpIOp>(
@@ -5073,7 +5058,7 @@ mlir::Value IntrinsicLibrary::genMask(mlir::Type resultType,
assert(args.size() == 2);
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
mlir::Value bitSize = builder.createIntegerConstant(
loc, resultType, resultType.getIntOrFloatBitWidth());
mlir::Value bitsToSet = builder.createConvert(loc, resultType, args[0]);
@@ -5206,7 +5191,7 @@ mlir::Value IntrinsicLibrary::genMergeBits(mlir::Type resultType,
mlir::Value i = builder.createConvert(loc, resultType, args[0]);
mlir::Value j = builder.createConvert(loc, resultType, args[1]);
mlir::Value mask = builder.createConvert(loc, resultType, args[2]);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
// MERGE_BITS(I, J, MASK) = IOR(IAND(I, MASK), IAND(J, NOT(MASK)))
mlir::Value notMask = builder.create<mlir::arith::XOrIOp>(loc, mask, ones);
@@ -5350,7 +5335,7 @@ void IntrinsicLibrary::genMvbits(llvm::ArrayRef<fir::ExtendedValue> args) {
auto to = builder.create<fir::LoadOp>(loc, resultType, toAddr);
mlir::Value topos = builder.createConvert(loc, resultType, unbox(args[4]));
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
- mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value ones = builder.createAllOnesInteger(loc, resultType);
mlir::Value bitSize = builder.createIntegerConstant(
loc, resultType, resultType.cast<mlir::IntegerType>().getWidth());
auto shiftCount = builder.create<mlir::arith::SubIOp>(loc, bitSize, len);
@@ -5429,7 +5414,7 @@ IntrinsicLibrary::genNorm2(mlir::Type resultType,
mlir::Value IntrinsicLibrary::genNot(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 1);
- mlir::Value allOnes = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value allOnes = builder.createAllOnesInteger(loc, resultType);
return builder.create<mlir::arith::XOrIOp>(loc, args[0], allOnes);
}
@@ -5872,7 +5857,7 @@ mlir::Value IntrinsicLibrary::genShiftA(mlir::Type resultType,
// the shift amount is equal to the element size.
// So if SHIFT is equal to the bit width then it is handled as a special case.
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
- mlir::Value minusOne = builder.createIntegerConstant(loc, resultType, -1);
+ mlir::Value minusOne = builder.createMinusOneInteger(loc, resultType);
mlir::Value valueIsNeg = builder.create<mlir::arith::CmpIOp>(
loc, mlir::arith::CmpIPredicate::slt, args[0], zero);
mlir::Value specialRes =
diff --git a/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp b/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp
index e588b19dded4f1..160118e2c050a3 100644
--- a/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp
@@ -2120,7 +2120,7 @@ PPCIntrinsicLibrary::genVecPerm(mlir::Type resultType,
if (isNativeVecElemOrderOnLE()) {
auto i8Ty{mlir::IntegerType::get(context, 8)};
auto v8Ty{mlir::VectorType::get(16, i8Ty)};
- auto negOne{builder.createIntegerConstant(loc, i8Ty, -1)};
+ auto negOne{builder.createMinusOneInteger(loc, i8Ty)};
auto vNegOne{
builder.create<mlir::vector::BroadcastOp>(loc, v8Ty, negOne)};
@@ -2209,7 +2209,7 @@ PPCIntrinsicLibrary::genVecSel(mlir::Type resultType,
auto vargs{convertVecArgs(builder, loc, vecTyInfos, argBases)};
auto i8Ty{mlir::IntegerType::get(builder.getContext(), 8)};
- auto negOne{builder.createIntegerConstant(loc, i8Ty, -1)};
+ auto negOne{builder.createMinusOneInteger(loc, i8Ty)};
// construct a constant <16 x i8> vector with value -1 for bitcast
auto bcVecTy{mlir::VectorType::get(16, i8Ty)};
diff --git a/flang/test/Lower/Intrinsics/maskl.f90 b/flang/test/Lower/Intrinsics/maskl.f90
index fab0122f6be747..ea77df480d5250 100644
--- a/flang/test/Lower/Intrinsics/maskl.f90
+++ b/flang/test/Lower/Intrinsics/maskl.f90
@@ -1,17 +1,18 @@
-! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: maskl_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}
subroutine maskl_test(a, b)
integer :: a
integer :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 32 : i32
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i32
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i32
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
b = maskl(a)
- ! CHECK: %[[C__0:.*]] = arith.constant 0 : i32
- ! CHECK: %[[C__1:.*]] = arith.constant -1 : i32
- ! CHECK: %[[BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_VAL]] : i32
! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i32
! CHECK: %[[IS0:.*]] = arith.cmpi eq, %[[A_VAL]], %[[C__0]] : i32
@@ -20,16 +21,17 @@ subroutine maskl_test(a, b)
end subroutine maskl_test
! CHECK-LABEL: maskl1_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i8>{{.*}}
subroutine maskl1_test(a, b)
integer :: a
integer(kind=1) :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 8 : i8
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i8
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i8
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
b = maskl(a, 1)
- ! CHECK: %[[C__0:.*]] = arith.constant 0 : i8
- ! CHECK: %[[C__1:.*]] = arith.constant -1 : i8
- ! CHECK: %[[BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[A_CONV:.*]] = fir.convert %[[A_VAL]] : (i32) -> i8
! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_CONV]] : i8
! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i8
@@ -39,16 +41,17 @@ subroutine maskl1_test(a, b)
end subroutine maskl1_test
! CHECK-LABEL: maskl2_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i16>{{.*}}
subroutine maskl2_test(a, b)
integer :: a
integer(kind=2) :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 16 : i16
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i16
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i16
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
b = maskl(a, 2)
- ! CHECK: %[[C__0:.*]] = arith.constant 0 : i16
- ! CHECK: %[[C__1:.*]] = arith.constant -1 : i16
- ! CHECK: %[[BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[A_CONV:.*]] = fir.convert %[[A_VAL]] : (i32) -> i16
! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_CONV]] : i16
! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i16
@@ -58,16 +61,17 @@ subroutine maskl2_test(a, b)
end subroutine maskl2_test
! CHECK-LABEL: maskl4_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}
subroutine maskl4_test(a, b)
integer :: a
integer(kind=4) :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 32 : i32
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i32
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i32
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
b = maskl(a, 4)
- ! CHECK: %[[C__0:.*]] = arith.constant 0 : i32
- ! CHECK: %[[C__1:.*]] = arith.constant -1 : i32
- ! CHECK: %[[BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_VAL]] : i32
! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i32
! CHECK: %[[IS0:.*]] = arith.cmpi eq, %[[A_VAL]], %[[C__0]] : i32
@@ -76,16 +80,17 @@ subroutine maskl4_test(a, b)
end subroutine maskl4_test
! CHECK-LABEL: maskl8_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i64>{{.*}}
subroutine maskl8_test(a, b)
integer :: a
integer(kind=8) :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 64 : i64
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i64
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i64
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
b = maskl(a, 8)
- ! CHECK: %[[C__0:.*]] = arith.constant 0 : i64
- ! CHECK: %[[C__1:.*]] = arith.constant -1 : i64
- ! CHECK: %[[BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[A_CONV:.*]] = fir.convert %[[A_VAL]] : (i32) -> i64
! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_CONV]] : i64
! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i64
@@ -94,8 +99,21 @@ subroutine maskl8_test(a, b)
! CHECK: fir.store %[[RESULT]] to %[[B]] : !fir.ref<i64>
end subroutine maskl8_test
-! TODO: Code containing 128-bit integer literals current breaks. This is
-! probably related to the issue linked below. When that is fixed, a test
-! for kind=16 should be added here.
-!
-! https://github.com/llvm/llvm-project/issues/56446
+subroutine maskl16_test(a, b)
+ integer :: a
+ integer(16) :: b
+ ! CHECK-DAG: %[[BITS:.*]] = arith.constant 128 : i128
+ ! CHECK-DAG: %[[C__1:.*]] = arith.constant -1 : i128
+ ! CHECK-DAG: %[[C__0:.*]] = arith.constant 0 : i128
+ ! CHECK: %[[A:.*]] = fir.declare %{{.*}}Ea
+ ! CHECK: %[[B:.*]] = fir.declare %{{.*}}Eb
+
+ ! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
+ b = maskl(a, 16)
+ ! CHECK: %[[A_CONV:.*]] = fir.convert %[[A_VAL]] : (i32) -> i128
+ ! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_CONV]] : i128
+ ! CHECK: %[[SHIFT:.*]] = arith.shli %[[C__1]], %[[LEN]] : i128
+ ! CHECK: %[[IS0:.*]] = arith.cmpi eq, %[[A_CONV]], %[[C__0]] : i128
+ ! CHECK: %[[RESULT:.*]] = arith.select %[[IS0]], %[[C__0]], %[[SHIFT]] : i128
+ ! CHECK: fir.store %[[RESULT]] to %[[B]] : !fir.ref<i128>
+end subroutine
d...
[truncated]
|
The lit tests are using both bbc -emit-fir/flang-new -fc1 -emit-fir |
Thanks Jean! |
The all one masks was not properly created for i128 types because builder.createIntegerConstant ended-up truncating -1 to something positive.
Add a builder.createAllOnesInteger/createMinusOneInteger helpers and use them where createIntegerConstant(..., -1) was used.
Add an assert in createIntegerConstant to catch negative numbers for i128 type.