summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeanPerier <jperier@nvidia.com>2024-04-08 10:18:56 +0200
committerGitHub <noreply@github.com>2024-04-08 10:18:56 +0200
commit8ddfb66903969224ebd4e10c1461d2be323f4798 (patch)
tree4a5fae8b9e98b398d9ed938a82160de779edad2f
parent81a7b6454e195f2051b76d9e5b1f0c430df0f502 (diff)
[flang] Fix MASKR/MASKL lowering for INTEGER(16) (#87496)
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.
-rw-r--r--flang/include/flang/Optimizer/Builder/FIRBuilder.h13
-rw-r--r--flang/lib/Lower/ConvertVariable.cpp2
-rw-r--r--flang/lib/Lower/DirectivesCommon.h2
-rw-r--r--flang/lib/Optimizer/Builder/FIRBuilder.cpp12
-rw-r--r--flang/lib/Optimizer/Builder/IntrinsicCall.cpp59
-rw-r--r--flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp4
-rw-r--r--flang/test/Lower/Intrinsics/maskl.f9072
-rw-r--r--flang/test/Lower/Intrinsics/maskr.f9072
8 files changed, 141 insertions, 95 deletions
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 940866b25d2f..e4c954159f71 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -164,9 +164,22 @@ public:
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 f59c784cff6f..01473f7f6cd7 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1469,7 +1469,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 6daa72b84d90..3ebf3fd965da 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 e4362b2f9e69..b09da4929a8a 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 5f6de9439b4b..4ee7258004fa 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);
@@ -5353,7 +5338,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);
@@ -5432,7 +5417,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);
}
@@ -5875,7 +5860,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 e588b19dded4..160118e2c050 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 fab0122f6be7..ea77df480d52 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
diff --git a/flang/test/Lower/Intrinsics/maskr.f90 b/flang/test/Lower/Intrinsics/maskr.f90
index 85077a19541c..8c87da2a5829 100644
--- a/flang/test/Lower/Intrinsics/maskr.f90
+++ b/flang/test/Lower/Intrinsics/maskr.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: maskr_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}
subroutine maskr_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 = maskr(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.shrui %[[C__1]], %[[LEN]] : i32
! CHECK: %[[IS0:.*]] = arith.cmpi eq, %[[A_VAL]], %[[C__0]] : i32
@@ -20,16 +21,17 @@ subroutine maskr_test(a, b)
end subroutine maskr_test
! CHECK-LABEL: maskr1_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i8>{{.*}}
subroutine maskr1_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 = maskr(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.shrui %[[C__1]], %[[LEN]] : i8
@@ -39,16 +41,17 @@ subroutine maskr1_test(a, b)
end subroutine maskr1_test
! CHECK-LABEL: maskr2_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i16>{{.*}}
subroutine maskr2_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 = maskr(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.shrui %[[C__1]], %[[LEN]] : i16
@@ -58,16 +61,17 @@ subroutine maskr2_test(a, b)
end subroutine maskr2_test
! CHECK-LABEL: maskr4_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}
subroutine maskr4_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 = maskr(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.shrui %[[C__1]], %[[LEN]] : i32
! CHECK: %[[IS0:.*]] = arith.cmpi eq, %[[A_VAL]], %[[C__0]] : i32
@@ -76,16 +80,17 @@ subroutine maskr4_test(a, b)
end subroutine maskr4_test
! CHECK-LABEL: maskr8_test
-! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i64>{{.*}}
subroutine maskr8_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 = maskr(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.shrui %[[C__1]], %[[LEN]] : i64
@@ -94,8 +99,21 @@ subroutine maskr8_test(a, b)
! CHECK: fir.store %[[RESULT]] to %[[B]] : !fir.ref<i64>
end subroutine maskr8_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 maskr16_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 = maskr(a, 16)
+ ! CHECK: %[[A_CONV:.*]] = fir.convert %[[A_VAL]] : (i32) -> i128
+ ! CHECK: %[[LEN:.*]] = arith.subi %[[BITS]], %[[A_CONV]] : i128
+ ! CHECK: %[[SHIFT:.*]] = arith.shrui %[[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