Skip to content

[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

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions flang/include/flang/Optimizer/Builder/FIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/DirectivesCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions flang/lib/Optimizer/Builder/FIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
59 changes: 22 additions & 37 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>(
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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 =
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)};

Expand Down Expand Up @@ -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)};
Expand Down
72 changes: 45 additions & 27 deletions flang/test/Lower/Intrinsics/maskl.f90
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Loading