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>);
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>);
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,
&I::genLbound,
{{{"array", asInquired}, {"dim", asValue}, {"kind", asValue}}},
/*isElemental=*/false},
+ {"leadz", &I::genLeadz},
{"len",
&I::genLen,
{{{"string", asInquired}, {"kind", asValue}}},
{"mask", asBox},
{"vector", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
+ {"popcnt", &I::genPopcnt},
+ {"poppar", &I::genPoppar},
{"present",
&I::genPresent,
{{{"a", asInquired}}},
&I::genSystemClock,
{{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}},
/*isElemental=*/false},
+ {"trailz", &I::genTrailz},
{"transfer",
&I::genTransfer,
{{{"source", asAddr}, {"mold", asAddr}, {"size", asValue}}},
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.
"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,
.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(); },
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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