aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorTarun Prabhu <tarun.prabhu@gmail.com>2022-07-21 23:05:33 -0600
committerTarun Prabhu <tarun.prabhu@gmail.com>2022-07-21 23:09:05 -0600
commitccfee46bc723d07b009078a2fb4a3a42bb1d4502 (patch)
tree34712dc6338a4c5409db135b4e773742f5ecd9d8 /flang
parenta50b9f9f1f89dcdfc163a9fcd76a6bcf20c26521 (diff)
downloadllvm-ccfee46bc723d07b009078a2fb4a3a42bb1d4502.zip
llvm-ccfee46bc723d07b009078a2fb4a3a42bb1d4502.tar.gz
llvm-ccfee46bc723d07b009078a2fb4a3a42bb1d4502.tar.bz2
[flang] Lower F08 bit population count intrinsics
Lower F08 bit population count intrinsics popcnt, poppar, leadz and trailz. popcnt, leadz and trailz are implemented using the corresponding MLIR math intrinsics. poppar is implemented in terms of popcnt. Differential Revision: https://reviews.llvm.org/D129584
Diffstat (limited to 'flang')
-rw-r--r--flang/lib/Lower/IntrinsicCall.cpp51
-rw-r--r--flang/test/Lower/Intrinsics/leadz.f9066
-rw-r--r--flang/test/Lower/Intrinsics/popcnt.f9066
-rw-r--r--flang/test/Lower/Intrinsics/poppar.f9076
-rw-r--r--flang/test/Lower/Intrinsics/trailz.f9066
5 files changed, 325 insertions, 0 deletions
diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 7d8aac5f..7bdfe50 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -510,6 +510,7 @@ struct IntrinsicLibrary {
mlir::Value genIshft(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genIshftc(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genLeadz(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genLenTrim(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genMatmul(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -527,6 +528,8 @@ struct IntrinsicLibrary {
mlir::Value genNot(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genPack(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genPopcnt(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ mlir::Value genPoppar(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genPresent(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genProduct(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genRandomInit(llvm::ArrayRef<fir::ExtendedValue>);
@@ -547,6 +550,7 @@ struct IntrinsicLibrary {
fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genTransfer(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genTranspose(mlir::Type,
@@ -793,6 +797,7 @@ static constexpr IntrinsicHandler handlers[]{
&I::genLbound,
{{{"array", asInquired}, {"dim", asValue}, {"kind", asValue}}},
/*isElemental=*/false},
+ {"leadz", &I::genLeadz},
{"len",
&I::genLen,
{{{"string", asInquired}, {"kind", asValue}}},
@@ -857,6 +862,8 @@ static constexpr IntrinsicHandler handlers[]{
{"mask", asBox},
{"vector", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
+ {"popcnt", &I::genPopcnt},
+ {"poppar", &I::genPoppar},
{"present",
&I::genPresent,
{{{"a", asInquired}}},
@@ -925,6 +932,7 @@ static constexpr IntrinsicHandler handlers[]{
&I::genSystemClock,
{{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}},
/*isElemental=*/false},
+ {"trailz", &I::genTrailz},
{"transfer",
&I::genTransfer,
{{{"source", asAddr}, {"mold", asAddr}, {"size", asValue}}},
@@ -3201,6 +3209,17 @@ mlir::Value IntrinsicLibrary::genIshftc(mlir::Type resultType,
return builder.create<mlir::arith::SelectOp>(loc, shiftIsNop, I, res);
}
+// LEADZ
+mlir::Value IntrinsicLibrary::genLeadz(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+
+ mlir::Value result =
+ builder.create<mlir::math::CountLeadingZerosOp>(loc, args);
+
+ return builder.createConvert(loc, resultType, result);
+}
+
// LEN
// Note that this is only used for an unrestricted intrinsic LEN call.
// Other uses of LEN are rewritten as descriptor inquiries by the front-end.
@@ -3497,6 +3516,27 @@ IntrinsicLibrary::genPack(mlir::Type resultType,
"unexpected result for PACK");
}
+// POPCNT
+mlir::Value IntrinsicLibrary::genPopcnt(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+
+ mlir::Value count = builder.create<mlir::math::CtPopOp>(loc, args);
+
+ return builder.createConvert(loc, resultType, count);
+}
+
+// POPPAR
+mlir::Value IntrinsicLibrary::genPoppar(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+
+ mlir::Value count = genPopcnt(resultType, args);
+ mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
+
+ return builder.create<mlir::arith::AndIOp>(loc, count, one);
+}
+
// PRESENT
fir::ExtendedValue
IntrinsicLibrary::genPresent(mlir::Type,
@@ -3776,6 +3816,17 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
.getResults()[0];
}
+// TRAILZ
+mlir::Value IntrinsicLibrary::genTrailz(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+
+ mlir::Value result =
+ builder.create<mlir::math::CountTrailingZerosOp>(loc, args);
+
+ return builder.createConvert(loc, resultType, result);
+}
+
static bool hasDefaultLowerBound(const fir::ExtendedValue &exv) {
return exv.match(
[](const fir::ArrayBoxValue &arr) { return arr.getLBounds().empty(); },
diff --git a/flang/test/Lower/Intrinsics/leadz.f90 b/flang/test/Lower/Intrinsics/leadz.f90
new file mode 100644
index 0000000..33efe45
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/leadz.f90
@@ -0,0 +1,66 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: leadz1_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i8>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine leadz1_test(a, b)
+ integer(1) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i8>
+ b = leadz(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctlz %[[AVAL]] : i8
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine leadz1_test
+
+! CHECK-LABEL: leadz2_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i16>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine leadz2_test(a, b)
+ integer(2) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i16>
+ b = leadz(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctlz %[[AVAL]] : i16
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine leadz2_test
+
+! CHECK-LABEL: leadz4_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i32>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine leadz4_test(a, b)
+ integer(4) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i32>
+ b = leadz(a)
+ ! CHECK: %[[RESULT:.*]] = math.ctlz %[[AVAL]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine leadz4_test
+
+! CHECK-LABEL: leadz8_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i64>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine leadz8_test(a, b)
+ integer(8) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i64>
+ b = leadz(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctlz %[[AVAL]] : i64
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine leadz8_test
+
+! CHECK-LABEL: leadz16_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i128>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine leadz16_test(a, b)
+ integer(16) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i128>
+ b = leadz(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctlz %[[AVAL]] : i128
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine leadz16_test
diff --git a/flang/test/Lower/Intrinsics/popcnt.f90 b/flang/test/Lower/Intrinsics/popcnt.f90
new file mode 100644
index 0000000..7e5785d
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/popcnt.f90
@@ -0,0 +1,66 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: popcnt1_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i8>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine popcnt1_test(a, b)
+ integer(1) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i8>
+ b = popcnt(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i8
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine popcnt1_test
+
+! CHECK-LABEL: popcnt2_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i16>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine popcnt2_test(a, b)
+ integer(2) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i16>
+ b = popcnt(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i16
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine popcnt2_test
+
+! CHECK-LABEL: popcnt4_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i32>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine popcnt4_test(a, b)
+ integer(4) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i32>
+ b = popcnt(a)
+ ! CHECK: %[[RESULT:.*]] = math.ctpop %[[AVAL]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine popcnt4_test
+
+! CHECK-LABEL: popcnt8_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i64>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine popcnt8_test(a, b)
+ integer(8) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i64>
+ b = popcnt(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i64
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine popcnt8_test
+
+! CHECK-LABEL: popcnt16_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i128>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine popcnt16_test(a, b)
+ integer(16) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i128>
+ b = popcnt(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i128
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine popcnt16_test
diff --git a/flang/test/Lower/Intrinsics/poppar.f90 b/flang/test/Lower/Intrinsics/poppar.f90
new file mode 100644
index 0000000..7141829
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/poppar.f90
@@ -0,0 +1,76 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: poppar1_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i8>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine poppar1_test(a, b)
+ integer(1) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i8>
+ b = poppar(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i8
+ ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i8) -> i32
+ ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine poppar1_test
+
+! CHECK-LABEL: poppar2_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i16>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine poppar2_test(a, b)
+ integer(2) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i16>
+ b = poppar(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i16
+ ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i16) -> i32
+ ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine poppar2_test
+
+! CHECK-LABEL: poppar4_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i32>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine poppar4_test(a, b)
+ integer(4) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i32>
+ b = poppar(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i32
+ ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[RESULT:.*]] = arith.andi %[[COUNT]], %[[C1]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine poppar4_test
+
+! CHECK-LABEL: poppar8_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i64>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine poppar8_test(a, b)
+ integer(8) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i64>
+ b = poppar(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i64
+ ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i64) -> i32
+ ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine poppar8_test
+
+! CHECK-LABEL: poppar16_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i128>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine poppar16_test(a, b)
+ integer(16) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i128>
+ b = poppar(a)
+ ! CHECK: %[[COUNT:.*]] = math.ctpop %[[AVAL]] : i128
+ ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i128) -> i32
+ ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine poppar16_test
diff --git a/flang/test/Lower/Intrinsics/trailz.f90 b/flang/test/Lower/Intrinsics/trailz.f90
new file mode 100644
index 0000000..db05f31
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/trailz.f90
@@ -0,0 +1,66 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: trailz1_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i8>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine trailz1_test(a, b)
+ integer(1) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i8>
+ b = trailz(a)
+ ! CHECK: %[[COUNT:.*]] = math.cttz %[[AVAL]] : i8
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine trailz1_test
+
+! CHECK-LABEL: trailz2_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i16>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine trailz2_test(a, b)
+ integer(2) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i16>
+ b = trailz(a)
+ ! CHECK: %[[COUNT:.*]] = math.cttz %[[AVAL]] : i16
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine trailz2_test
+
+! CHECK-LABEL: trailz4_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i32>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine trailz4_test(a, b)
+ integer(4) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i32>
+ b = trailz(a)
+ ! CHECK: %[[RESULT:.*]] = math.cttz %[[AVAL]] : i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine trailz4_test
+
+! CHECK-LABEL: trailz8_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i64>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine trailz8_test(a, b)
+ integer(8) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i64>
+ b = trailz(a)
+ ! CHECK: %[[COUNT:.*]] = math.cttz %[[AVAL]] : i64
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine trailz8_test
+
+! CHECK-LABEL: trailz16_test
+! CHECK-SAME: %[[AREF:.*]]: !fir.ref<i128>{{.*}}, %[[BREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine trailz16_test(a, b)
+ integer(16) :: a
+ integer :: b
+
+ ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref<i128>
+ b = trailz(a)
+ ! CHECK: %[[COUNT:.*]] = math.cttz %[[AVAL]] : i128
+ ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32
+ ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref<i32>
+end subroutine trailz16_test