Skip to content

Commit 2a40e62

Browse files
authored
Merge pull request #1024 from flang-compiler/aperry-eoshift
Lowering for EOSHIFT intrinsic
2 parents 3a164ae + bffea5c commit 2a40e62

File tree

5 files changed

+244
-0
lines changed

5 files changed

+244
-0
lines changed

flang/include/flang/Optimizer/Builder/Runtime/Transformational.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ void genCshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
2727
mlir::Value resultBox, mlir::Value arrayBox,
2828
mlir::Value shiftBox);
2929

30+
void genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
31+
mlir::Value resultBox, mlir::Value arrayBox,
32+
mlir::Value shiftBox, mlir::Value boundBox, mlir::Value dimBox);
33+
34+
void genEoshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
35+
mlir::Value resultBox, mlir::Value arrayBox,
36+
mlir::Value shiftBox, mlir::Value boundBox);
37+
3038
void genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
3139
mlir::Value matrixABox, mlir::Value matrixBBox,
3240
mlir::Value resultBox);

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ struct IntrinsicLibrary {
457457
fir::ExtendedValue genDotProduct(mlir::Type,
458458
llvm::ArrayRef<fir::ExtendedValue>);
459459
mlir::Value genDprod(mlir::Type, llvm::ArrayRef<mlir::Value>);
460+
fir::ExtendedValue genEoshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
460461
mlir::Value genExponent(mlir::Type, llvm::ArrayRef<mlir::Value>);
461462
template <Extremum, ExtremumBehavior>
462463
mlir::Value genExtremum(mlir::Type, llvm::ArrayRef<mlir::Value>);
@@ -681,6 +682,13 @@ static constexpr IntrinsicHandler handlers[]{
681682
{{{"vector_a", asAddr}, {"vector_b", asAddr}}},
682683
/*isElemental=*/false},
683684
{"dprod", &I::genDprod},
685+
{"eoshift",
686+
&I::genEoshift,
687+
{{{"array", asAddr},
688+
{"shift", asAddr},
689+
{"boundary", asAddr},
690+
{"dim", asValue}}},
691+
/*isElemental=*/false},
684692
{"exponent", &I::genExponent},
685693
{"floor", &I::genFloor},
686694
{"fraction", &I::genFraction},
@@ -2123,6 +2131,55 @@ mlir::Value IntrinsicLibrary::genDprod(mlir::Type resultType,
21232131
return builder.create<mlir::MulFOp>(loc, a, b);
21242132
}
21252133

2134+
// EOSHIFT
2135+
fir::ExtendedValue
2136+
IntrinsicLibrary::genEoshift(mlir::Type resultType,
2137+
llvm::ArrayRef<fir::ExtendedValue> args) {
2138+
assert(args.size() == 4);
2139+
2140+
// Handle required ARRAY argument
2141+
fir::BoxValue arrayBox = builder.createBox(loc, args[0]);
2142+
auto array = fir::getBase(arrayBox);
2143+
auto arrayRank = arrayBox.rank();
2144+
2145+
// Create mutable fir.box to be passed to the runtime for the result.
2146+
auto resultArrayType = builder.getVarLenSeqTy(resultType, arrayRank);
2147+
auto resultMutableBox =
2148+
fir::factory::createTempMutableBox(builder, loc, resultArrayType);
2149+
auto resultIrBox =
2150+
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
2151+
2152+
// Handle optional BOUNDARY argument
2153+
auto boundary = isAbsent(args[2])
2154+
? builder.create<fir::AbsentOp>(
2155+
loc, fir::BoxType::get(builder.getNoneType()))
2156+
: builder.createBox(loc, args[2]);
2157+
2158+
if (arrayRank == 1) {
2159+
// Vector case
2160+
// Handle required SHIFT argument as a scalar
2161+
auto shiftAddr = args[1].getUnboxed();
2162+
assert(shiftAddr && "nonscalar EOSHIFT SHIFT argument");
2163+
auto shift = builder.create<fir::LoadOp>(loc, *shiftAddr);
2164+
fir::runtime::genEoshiftVector(builder, loc, resultIrBox, array, shift,
2165+
boundary);
2166+
} else {
2167+
// Non-vector case
2168+
// Handle required SHIFT argument as an array
2169+
auto shift = builder.createBox(loc, args[1]);
2170+
2171+
// Handle optional DIM argument
2172+
auto dim =
2173+
isAbsent(args[3])
2174+
? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
2175+
: fir::getBase(args[3]);
2176+
fir::runtime::genEoshift(builder, loc, resultIrBox, array, shift, boundary,
2177+
dim);
2178+
}
2179+
return readAndAddCleanUp(resultMutableBox, resultType,
2180+
"unexpected result for EOSHIFT");
2181+
}
2182+
21262183
// EXPONENT
21272184
mlir::Value IntrinsicLibrary::genExponent(mlir::Type resultType,
21282185
llvm::ArrayRef<mlir::Value> args) {

flang/lib/Optimizer/Builder/Runtime/Transformational.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,42 @@ void fir::runtime::genCshiftVector(fir::FirOpBuilder &builder,
5050
builder.create<fir::CallOp>(loc, cshiftFunc, args);
5151
}
5252

53+
/// Generate call to Eoshift intrinsic
54+
void fir::runtime::genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
55+
mlir::Value resultBox, mlir::Value arrayBox,
56+
mlir::Value shiftBox, mlir::Value boundBox,
57+
mlir::Value dimBox) {
58+
auto eoshiftFunc =
59+
fir::runtime::getRuntimeFunc<mkRTKey(Eoshift)>(loc, builder);
60+
auto fTy = eoshiftFunc.getType();
61+
auto sourceFile = fir::factory::locationToFilename(builder, loc);
62+
auto sourceLine =
63+
fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
64+
auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
65+
arrayBox, shiftBox, boundBox,
66+
dimBox, sourceFile, sourceLine);
67+
builder.create<fir::CallOp>(loc, eoshiftFunc, args);
68+
}
69+
70+
/// Generate call to the vector version of the Eoshift intrinsic
71+
void fir::runtime::genEoshiftVector(fir::FirOpBuilder &builder,
72+
mlir::Location loc, mlir::Value resultBox,
73+
mlir::Value arrayBox, mlir::Value shiftBox,
74+
mlir::Value boundBox) {
75+
auto eoshiftFunc =
76+
fir::runtime::getRuntimeFunc<mkRTKey(EoshiftVector)>(loc, builder);
77+
auto fTy = eoshiftFunc.getType();
78+
79+
auto sourceFile = fir::factory::locationToFilename(builder, loc);
80+
auto sourceLine =
81+
fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
82+
83+
auto args =
84+
fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
85+
shiftBox, boundBox, sourceFile, sourceLine);
86+
builder.create<fir::CallOp>(loc, eoshiftFunc, args);
87+
}
88+
5389
/// Generate call to Matmul intrinsic runtime routine.
5490
void fir::runtime::genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
5591
mlir::Value resultBox, mlir::Value matrixABox,

flang/test/Intrinsics/eoshift.f90

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
! RUN: bbc %s -o - | FileCheck %s
2+
3+
! CHECK: _QQmain
4+
program test_eoshift
5+
integer, dimension(3,3) :: a
6+
real, dimension(3,3) :: b
7+
logical, dimension(3,3) :: c
8+
character(3), dimension(3,3) :: d
9+
integer, dimension(3) :: v
10+
11+
! INTEGER vector
12+
v = (/ 1, 2, 3 /)
13+
print '(3i3)', v
14+
15+
v = EOSHIFT(v, SHIFT=1, BOUNDARY=-1)
16+
print *
17+
print '(3i3)', v
18+
19+
! INTEGER array
20+
a = reshape( (/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), (/ 3, 3 /))
21+
print *
22+
print '(3i3)', a(1,:)
23+
print '(3i3)', a(2,:)
24+
print '(3i3)', a(3,:)
25+
26+
a = EOSHIFT(a, SHIFT=(/1, 2, 1/), BOUNDARY=-5, DIM=2)
27+
print *
28+
print '(3i3)', a(1,:)
29+
print '(3i3)', a(2,:)
30+
print '(3i3)', a(3,:)
31+
32+
! REAL array
33+
b = reshape( (/ 1., 2., 3., 4., 5., 6., 7., 8., 9. /), (/ 3, 3 /))
34+
print *
35+
print '(3f5.1)', b(1,:)
36+
print '(3f5.1)', b(2,:)
37+
print '(3f5.1)', b(3,:)
38+
39+
b = EOSHIFT(b, SHIFT=(/1, 2, 1/), BOUNDARY=-1.0, DIM=1)
40+
print *
41+
print '(3f5.1)', b(1,:)
42+
print '(3f5.1)', b(2,:)
43+
print '(3f5.1)', b(3,:)
44+
45+
! LOGICAL array, no BOUNDARY or DIM given
46+
c = reshape( (/ .true., .true., .true., .true., .true., .true., .true., .true., .true. /), (/ 3, 3 /))
47+
print *
48+
print '(3l3)', c(1,:)
49+
print '(3l3)', c(2,:)
50+
print '(3l3)', c(3,:)
51+
52+
c = EOSHIFT(c, SHIFT=(/1, 2, 1/))
53+
print *
54+
print '(3l3)', c(1,:)
55+
print '(3l3)', c(2,:)
56+
print '(3l3)', c(3,:)
57+
58+
! CHARACTER array, no BOUNDARY or DIM given
59+
d = reshape( (/ "foo", "foo", "foo", "bar", "bar", "bar", "baz", "baz", "baz" /), (/ 3, 3 /))
60+
print *
61+
print '(3a5)', d(1,:)
62+
print '(3a5)', d(2,:)
63+
print '(3a5)', d(3,:)
64+
65+
d = EOSHIFT(d, SHIFT=(/1, 2, 1/))
66+
print *
67+
print '(3a5)', d(1,:)
68+
print '(3a5)', d(2,:)
69+
print '(3a5)', d(3,:)
70+
71+
end program test_eoshift
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
3+
! CHECK-LABEL: eoshift_test1
4+
subroutine eoshift_test1(arr, shift)
5+
logical, dimension(3) :: arr, res
6+
integer :: shift
7+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>> {uniq_name = ""}
8+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x!fir.logical<4>> {bindc_name = "res", uniq_name = "_QFeoshift_test1Eres"}
9+
! CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<3x!fir.logical<4>>
10+
! CHECK: %[[arr:.*]] = fir.embox %arg0({{.*}}) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<3x!fir.logical<4>>>
11+
! CHECK: %[[bits:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.logical<4>>>
12+
! CHECK: %[[init:.*]] = fir.embox %[[bits]]({{.*}}) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>
13+
! CHECK: fir.store %[[init]] to %[[resBox]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>
14+
! CHECK: %[[boundBox:.*]] = fir.absent !fir.box<none>
15+
! CHECK: %[[shift:.*]] = fir.load %arg1 : !fir.ref<i32>
16+
17+
res = eoshift(arr, shift)
18+
19+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>) -> !fir.ref<!fir.box<none>>
20+
! CHECK: %[[arrBox:.*]] = fir.convert %[[arr]] : (!fir.box<!fir.array<3x!fir.logical<4>>>) -> !fir.box<none>
21+
! CHECK: %[[shiftBox:.*]] = fir.convert %[[shift]] : (i32) -> i64
22+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshiftVector(%[[resIRBox]], %[[arrBox]], %[[shiftBox]], %[[boundBox]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i64, !fir.box<none>, !fir.ref<i8>, i32) -> none
23+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x!fir.logical<4>>, !fir.array<3x!fir.logical<4>>, !fir.ref<!fir.array<3x!fir.logical<4>>>
24+
end subroutine eoshift_test1
25+
26+
! CHECK-LABEL: eoshift_test2
27+
subroutine eoshift_test2(arr, shift, bound, dim)
28+
integer, dimension(3,3) :: arr, res
29+
integer, dimension(3) :: shift
30+
integer :: bound, dim
31+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi32>>> {uniq_name = ""}
32+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "res", uniq_name = "_QFeoshift_test2Eres"}
33+
!CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x3xi32>>, !fir.shape<2>) -> !fir.array<3x3xi32>
34+
! CHECK: %[[dim:.*]] = fir.load %arg3 : !fir.ref<i32>
35+
36+
res = eoshift(arr, shift, bound, dim)
37+
38+
! CHECK: %[[arr:.*]] = fir.embox %arg0({{.*}}) : (!fir.ref<!fir.array<3x3xi32>>, !fir.shape<2>) -> !fir.box<!fir.array<3x3xi32>>
39+
! CHECK: %[[boundBox:.*]] = fir.embox %arg2 : (!fir.ref<i32>) -> !fir.box<i32>
40+
! CHECK: %[[shiftBox:.*]] = fir.embox %arg1({{.*}}) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
41+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> !fir.ref<!fir.box<none>>
42+
! CHECK: %[[arrBox:.*]] = fir.convert %[[arr]] : (!fir.box<!fir.array<3x3xi32>>) -> !fir.box<none>
43+
! CHECK: %[[shiftBoxNone:.*]] = fir.convert %[[shiftBox]] : (!fir.box<!fir.array<3xi32>>) -> !fir.box<none>
44+
! CHECK: %[[boundBoxNone:.*]] = fir.convert %[[boundBox]] : (!fir.box<i32>) -> !fir.box<none>
45+
46+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshift(%[[resIRBox]], %[[arrBox]], %[[shiftBoxNone]], %[[boundBoxNone]], %[[dim]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
47+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x3xi32>, !fir.array<3x3xi32>, !fir.ref<!fir.array<3x3xi32>>
48+
end subroutine eoshift_test2
49+
50+
! CHECK-LABEL: eoshift_test3
51+
subroutine eoshift_test3(arr, shift, dim)
52+
character(4), dimension(3,3) :: arr, res
53+
integer :: shift, dim
54+
55+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>> {uniq_name = ""}
56+
! CHECK: %[[arr:.*]]:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
57+
! CHECK: %[[array:.*]] = fir.convert %[[arr]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<3x3x!fir.char<1,4>>>
58+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x3x!fir.char<1,4>> {bindc_name = "res", uniq_name = "_QFeoshift_test3Eres"}
59+
! CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x3x!fir.char<1,4>>>, !fir.shape<2>) -> !fir.array<3x3x!fir.char<1,4>>
60+
! CHECK: %[[dim:.*]] = fir.load %arg2 : !fir.ref<i32>
61+
! CHECK: %[[arrayBox:.*]] = fir.embox %[[array]]({{.*}}) : (!fir.ref<!fir.array<3x3x!fir.char<1,4>>>, !fir.shape<2>) -> !fir.box<!fir.array<3x3x!fir.char<1,4>>>
62+
63+
res = eoshift(arr, SHIFT=shift, DIM=dim)
64+
65+
! CHECK: %[[boundBox:.*]] = fir.absent !fir.box<none>
66+
! CHECK: %[[shiftBox:.*]] = fir.embox %arg1 : (!fir.ref<i32>) -> !fir.box<i32>
67+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<none>>
68+
! CHECK: %[[arrayBoxNone:.*]] = fir.convert %[[arrayBox]] : (!fir.box<!fir.array<3x3x!fir.char<1,4>>>) -> !fir.box<none>
69+
! CHECK: %[[shiftBoxNone:.*]] = fir.convert %[[shiftBox]] : (!fir.box<i32>) -> !fir.box<none>
70+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshift(%[[resIRBox]], %[[arrayBoxNone]], %[[shiftBoxNone]], %[[boundBox]], %[[dim]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
71+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x3x!fir.char<1,4>>, !fir.array<3x3x!fir.char<1,4>>, !fir.ref<!fir.array<3x3x!fir.char<1,4>>>
72+
end subroutine eoshift_test3

0 commit comments

Comments
 (0)