[flang-commits] [flang] [flang] Fix MASKR/MASKL lowering for INTEGER(16) (PR #87496)

via flang-commits flang-commits at lists.llvm.org
Fri Apr 5 02:20:25 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: None (jeanPerier)

<details>
<summary>Changes</summary>

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.

---

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:

- (modified) flang/include/flang/Optimizer/Builder/FIRBuilder.h (+13) 
- (modified) flang/lib/Lower/ConvertVariable.cpp (+1-1) 
- (modified) flang/lib/Lower/DirectivesCommon.h (+1-1) 
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+12) 
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+22-37) 
- (modified) flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp (+2-2) 
- (modified) flang/test/Lower/Intrinsics/maskl.f90 (+45-27) 
- (modified) flang/test/Lower/Intrinsics/maskr.f90 (+45-27) 


``````````diff
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]

``````````

</details>


https://github.com/llvm/llvm-project/pull/87496


More information about the flang-commits mailing list