Skip to content

Commit 4d20964

Browse files
banach-spaceclementvalschweitzpgimleairjeanPerier
committed
[flang][lowering] Add support for lowering of the merge intrinsics
This patch adds support for lowering of the `merge` intrinsics 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 Differential Revision: https://reviews.llvm.org/D121924 Co-authored-by: Valentin Clement <[email protected]> Co-authored-by: Eric Schweitz <[email protected]> Co-authored-by: Mark Leair <[email protected]> Co-authored-by: Jean Perier <[email protected]>
1 parent 33d020d commit 4d20964

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ struct IntrinsicLibrary {
493493
fir::ExtendedValue genMatmul(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
494494
fir::ExtendedValue genMaxloc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
495495
fir::ExtendedValue genMaxval(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
496+
fir::ExtendedValue genMerge(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
496497
fir::ExtendedValue genMinloc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
497498
fir::ExtendedValue genMinval(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
498499
mlir::Value genMod(mlir::Type, llvm::ArrayRef<mlir::Value>);
@@ -764,6 +765,7 @@ static constexpr IntrinsicHandler handlers[]{
764765
{"dim", asValue},
765766
{"mask", asBox, handleDynamicOptional}}},
766767
/*isElemental=*/false},
768+
{"merge", &I::genMerge},
767769
{"min", &I::genExtremum<Extremum::Min, ExtremumBehavior::MinMaxss>},
768770
{"minloc",
769771
&I::genMinloc,
@@ -2743,6 +2745,27 @@ IntrinsicLibrary::genMaxval(mlir::Type resultType,
27432745
stmtCtx, "unexpected result for Maxval", args);
27442746
}
27452747

2748+
// MERGE
2749+
fir::ExtendedValue
2750+
IntrinsicLibrary::genMerge(mlir::Type,
2751+
llvm::ArrayRef<fir::ExtendedValue> args) {
2752+
assert(args.size() == 3);
2753+
mlir::Value arg0 = fir::getBase(args[0]);
2754+
mlir::Value arg1 = fir::getBase(args[1]);
2755+
mlir::Value arg2 = fir::getBase(args[2]);
2756+
mlir::Type type0 = fir::unwrapRefType(arg0.getType());
2757+
bool isCharRslt = fir::isa_char(type0); // result is same as first argument
2758+
mlir::Value mask = builder.createConvert(loc, builder.getI1Type(), arg2);
2759+
auto rslt = builder.create<mlir::arith::SelectOp>(loc, mask, arg0, arg1);
2760+
if (isCharRslt) {
2761+
// Need a CharBoxValue for character results
2762+
const fir::CharBoxValue *charBox = args[0].getCharBox();
2763+
fir::CharBoxValue charRslt(rslt, charBox->getLen());
2764+
return charRslt;
2765+
}
2766+
return rslt;
2767+
}
2768+
27462769
// MINLOC
27472770
fir::ExtendedValue
27482771
IntrinsicLibrary::genMinloc(mlir::Type resultType,

flang/test/Lower/Intrinsics/merge.f90

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
3+
4+
! CHECK-LABEL: func @_QPmerge_test(
5+
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.char<1>>{{.*}}, %[[arg1:.*]]: index{{.*}}, %[[arg2:[^:]+]]: !fir.boxchar<1>{{.*}}, %[[arg3:[^:]+]]: !fir.boxchar<1>{{.*}}, %[[arg4:.*]]: !fir.ref<!fir.logical<4>>{{.*}}) -> !fir.boxchar<1> {
6+
function merge_test(o1, o2, mask)
7+
character :: o1, o2, merge_test
8+
logical :: mask
9+
merge_test = merge(o1, o2, mask)
10+
! CHECK: %[[a0:.*]]:2 = fir.unboxchar %[[arg2]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
11+
! CHECK-DAG: %[[a1:.*]]:2 = fir.unboxchar %[[arg3]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
12+
! CHECK: %[[a2:.*]] = fir.load %[[arg4]] : !fir.ref<!fir.logical<4>>
13+
! CHECK: %[[a3:.*]] = fir.convert %[[a2]] : (!fir.logical<4>) -> i1
14+
! CHECK: %[[a4:.*]] = arith.select %[[a3]], %[[a0]]#0, %[[a1]]#0 : !fir.ref<!fir.char<1,?>>
15+
! CHECK-DAG: %{{.*}} = fir.convert %[[a4]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
16+
end
17+
18+
! CHECK-LABEL: func @_QPmerge_test2(
19+
! CHECK-SAME: %[[arg0:[^:]+]]: !fir.ref<i32>{{.*}}, %[[arg1:[^:]+]]: !fir.ref<i32>{{.*}}, %[[arg2:.*]]: !fir.ref<!fir.logical<4>>{{.*}}) -> i32 {
20+
function merge_test2(o1, o2, mask)
21+
integer :: o1, o2, merge_test2
22+
logical :: mask
23+
merge_test2 = merge(o1, o2, mask)
24+
! CHECK: %[[a1:.*]] = fir.load %[[arg0]] : !fir.ref<i32>
25+
! CHECK: %[[a2:.*]] = fir.load %[[arg1]] : !fir.ref<i32>
26+
! CHECK: %[[a3:.*]] = fir.load %[[arg2]] : !fir.ref<!fir.logical<4>>
27+
! CHECK: %[[a4:.*]] = fir.convert %[[a3]] : (!fir.logical<4>) -> i1
28+
! CHECK: %{{.*}} = arith.select %[[a4]], %[[a1]], %[[a2]] : i32
29+
end
30+
31+
! CHECK-LABEL: func @_QPmerge_test3(
32+
! CHECK-SAME: %[[arg0:[^:]+]]: !fir.ref<!fir.array<10x!fir.type<_QFmerge_test3Tt{i:i32}>>>{{.*}}, %[[arg1:[^:]+]]: !fir.ref<!fir.type<_QFmerge_test3Tt{i:i32}>>{{.*}}, %[[arg2:[^:]+]]: !fir.ref<!fir.type<_QFmerge_test3Tt{i:i32}>>{{.*}}, %[[arg3:.*]]: !fir.ref<!fir.logical<4>>{{.*}}) {
33+
subroutine merge_test3(result, o1, o2, mask)
34+
type t
35+
integer :: i
36+
end type
37+
type(t) :: result(10), o1, o2
38+
logical :: mask
39+
result = merge(o1, o2, mask)
40+
! CHECK: %[[mask:.*]] = fir.load %[[arg3]] : !fir.ref<!fir.logical<4>>
41+
! CHECK: %[[mask_cast:.*]] = fir.convert %[[mask]] : (!fir.logical<4>) -> i1
42+
! CHECK: = arith.select %[[mask_cast]], %[[arg1]], %[[arg2]] : !fir.ref<!fir.type<_QFmerge_test3Tt{i:i32}>>
43+
end

0 commit comments

Comments
 (0)