Skip to content

Commit 63bbac1

Browse files
committed
[flang][lowering] Add support for lowering of the ibset intrinsic
This patch adds support for lowering of the `ibset` intrinsic from Fortran to the FIR dialect of MLIR. This is part of the upstreaming effort from the `fir-dev` branch in [1]. [1] https://github.com/flang-compiler/f18-llvm-project Co-authored-by: Jean Perier <[email protected]> Co-authored-by: Valentin Clement <[email protected]> Co-authored-by: V Donaldson <[email protected]> Differential Revision: https://reviews.llvm.org/D121717
1 parent 91fad11 commit 63bbac1

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ struct IntrinsicLibrary {
449449
/// in the llvm::ArrayRef.
450450
mlir::Value genIand(mlir::Type, llvm::ArrayRef<mlir::Value>);
451451
mlir::Value genIbits(mlir::Type, llvm::ArrayRef<mlir::Value>);
452+
mlir::Value genIbset(mlir::Type, llvm::ArrayRef<mlir::Value>);
452453
fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
453454
fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
454455
fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -595,6 +596,7 @@ static constexpr IntrinsicHandler handlers[]{
595596
/*isElemental=*/false},
596597
{"iand", &I::genIand},
597598
{"ibits", &I::genIbits},
599+
{"ibset", &I::genIbset},
598600
{"len",
599601
&I::genLen,
600602
{{{"string", asInquired}, {"kind", asValue}}},
@@ -1682,6 +1684,20 @@ mlir::Value IntrinsicLibrary::genIbits(mlir::Type resultType,
16821684
return builder.create<mlir::arith::SelectOp>(loc, lenIsZero, zero, res2);
16831685
}
16841686

1687+
// IBSET
1688+
mlir::Value IntrinsicLibrary::genIbset(mlir::Type resultType,
1689+
llvm::ArrayRef<mlir::Value> args) {
1690+
// A conformant IBSET(I,POS) call satisfies:
1691+
// POS >= 0
1692+
// POS < BIT_SIZE(I)
1693+
// Return: I | (1 << POS)
1694+
assert(args.size() == 2);
1695+
mlir::Value pos = builder.createConvert(loc, resultType, args[1]);
1696+
mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
1697+
auto mask = builder.create<mlir::arith::ShLIOp>(loc, one, pos);
1698+
return builder.create<mlir::arith::OrIOp>(loc, args[0], mask);
1699+
}
1700+
16851701
// LEN
16861702
// Note that this is only used for an unrestricted intrinsic LEN call.
16871703
// Other uses of LEN are rewritten as descriptor inquiries by the front-end.

flang/test/Lower/Intrinsics/ibset.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
3+
4+
! CHECK-LABEL: ibset_test
5+
function ibset_test(i, j)
6+
! CHECK-DAG: %[[result:.*]] = fir.alloca i32 {bindc_name = "ibset_test"
7+
! CHECK-DAG: %[[i:.*]] = fir.load %arg0 : !fir.ref<i32>
8+
! CHECK-DAG: %[[j:.*]] = fir.load %arg1 : !fir.ref<i32>
9+
! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 1 : i32
10+
! CHECK: %[[VAL_6:.*]] = arith.shli %[[VAL_5]], %[[j]] : i32
11+
! CHECK: %[[VAL_7:.*]] = arith.ori %[[i]], %[[VAL_6]] : i32
12+
! CHECK: fir.store %[[VAL_7]] to %[[result]] : !fir.ref<i32>
13+
! CHECK: %[[VAL_8:.*]] = fir.load %[[result]] : !fir.ref<i32>
14+
! CHECK: return %[[VAL_8]] : i32
15+
ibset_test = ibset(i, j)
16+
end
17+

0 commit comments

Comments
 (0)