Skip to content

Commit 8d713c0

Browse files
committed
Address comments
1 parent 9e4c9dd commit 8d713c0

File tree

5 files changed

+110
-59
lines changed

5 files changed

+110
-59
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,20 @@ void genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
225225
mlir::Value maskBox);
226226

227227
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
228-
/// that does not take a dim argument.
228+
/// that does not take a dim argument and store the result in the provided
229+
/// result value. This is used for COMPLEX, CHARACTER and DERIVED TYPES.
230+
void genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
231+
mlir::Value arrayBox, mlir::Value operation, mlir::Value maskBox,
232+
mlir::Value identity, mlir::Value ordered,
233+
mlir::Value resultBox);
234+
235+
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
236+
/// that does not take a dim argument and return a scalare result. This is used
237+
/// for REAL, INTEGER and LOGICAL TYPES.
229238
mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
230239
mlir::Value arrayBox, mlir::Value operation,
231240
mlir::Value maskBox, mlir::Value identity,
232-
mlir::Value ordered, mlir::Value resultBox);
241+
mlir::Value ordered);
233242

234243
} // namespace fir::runtime
235244

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,8 @@ static constexpr IntrinsicHandler handlers[]{
526526
{"operation", asAddr},
527527
{"dim", asValue},
528528
{"mask", asBox, handleDynamicOptional},
529-
{"identity", asAddr},
530-
{"ordered", asValue}}},
529+
{"identity", asAddr, handleDynamicOptional},
530+
{"ordered", asValue, handleDynamicOptional}}},
531531
/*isElemental=*/false},
532532
{"repeat",
533533
&I::genRepeat,
@@ -5749,7 +5749,7 @@ IntrinsicLibrary::genReduce(mlir::Type resultType,
57495749
mlir::Type eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
57505750

57515751
// Handle optional arguments
5752-
bool absentDim = isStaticallyAbsent(args[1]);
5752+
bool absentDim = isStaticallyAbsent(args[2]);
57535753

57545754
auto mask = isStaticallyAbsent(args[3])
57555755
? builder.create<fir::AbsentOp>(
@@ -5762,7 +5762,7 @@ IntrinsicLibrary::genReduce(mlir::Type resultType,
57625762
: fir::getBase(args[4]);
57635763

57645764
mlir::Value ordered = isStaticallyAbsent(args[5])
5765-
? builder.createBool(loc, true)
5765+
? builder.createBool(loc, false)
57665766
: fir::getBase(args[5]);
57675767

57685768
// We call the type specific versions because the result is scalar
@@ -5787,10 +5787,8 @@ IntrinsicLibrary::genReduce(mlir::Type resultType,
57875787
// Handle cleanup of allocatable result descriptor and return
57885788
return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE");
57895789
}
5790-
auto resultBox = builder.create<fir::AbsentOp>(
5791-
loc, fir::BoxType::get(builder.getI1Type()));
57925790
return fir::runtime::genReduce(builder, loc, array, operation, mask,
5793-
identity, ordered, resultBox);
5791+
identity, ordered);
57945792
}
57955793
TODO(loc, "reduce with array result");
57965794
}

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

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@ struct ForcedReduceComplex10 {
521521
auto refTy = fir::ReferenceType::get(ty);
522522
auto i1Ty = mlir::IntegerType::get(ctx, 1);
523523
return mlir::FunctionType::get(
524-
ctx, {ty, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {});
524+
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
525+
{});
525526
};
526527
}
527528
};
@@ -541,7 +542,8 @@ struct ForcedReduceComplex16 {
541542
auto refTy = fir::ReferenceType::get(ty);
542543
auto i1Ty = mlir::IntegerType::get(ctx, 1);
543544
return mlir::FunctionType::get(
544-
ctx, {ty, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {});
545+
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
546+
{});
545547
};
546548
}
547549
};
@@ -1319,12 +1321,71 @@ void fir::runtime::genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
13191321
GEN_IALL_IANY_IPARITY(IParity)
13201322

13211323
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
1322-
/// that does have a scalar result.
1324+
/// that does not take a DIM argument and store result in the passed result
1325+
/// value.
1326+
void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
1327+
mlir::Value arrayBox, mlir::Value operation,
1328+
mlir::Value maskBox, mlir::Value identity,
1329+
mlir::Value ordered, mlir::Value resultBox) {
1330+
mlir::func::FuncOp func;
1331+
auto ty = arrayBox.getType();
1332+
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
1333+
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
1334+
auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
1335+
1336+
assert(resultBox && "expect non null value for the result");
1337+
assert((fir::isa_char(eleTy) || fir::isa_complex(eleTy) ||
1338+
fir::isa_derived(eleTy)) &&
1339+
"expect character, complex or derived-type");
1340+
1341+
mlir::MLIRContext *ctx = builder.getContext();
1342+
fir::factory::CharacterExprHelper charHelper{builder, loc};
1343+
1344+
if (eleTy == fir::ComplexType::get(ctx, 2))
1345+
func =
1346+
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2)>(loc, builder);
1347+
else if (eleTy == fir::ComplexType::get(ctx, 3))
1348+
func =
1349+
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3)>(loc, builder);
1350+
else if (eleTy == fir::ComplexType::get(ctx, 4))
1351+
func =
1352+
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4)>(loc, builder);
1353+
else if (eleTy == fir::ComplexType::get(ctx, 8))
1354+
func =
1355+
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8)>(loc, builder);
1356+
else if (eleTy == fir::ComplexType::get(ctx, 10))
1357+
func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10>(loc, builder);
1358+
else if (eleTy == fir::ComplexType::get(ctx, 16))
1359+
func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16>(loc, builder);
1360+
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
1361+
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);
1362+
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
1363+
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);
1364+
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
1365+
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar4)>(loc, builder);
1366+
else if (fir::isa_derived(eleTy))
1367+
func =
1368+
fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);
1369+
else
1370+
fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
1371+
1372+
auto fTy = func.getFunctionType();
1373+
auto sourceFile = fir::factory::locationToFilename(builder, loc);
1374+
auto sourceLine =
1375+
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
1376+
auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
1377+
auto args = fir::runtime::createArguments(
1378+
builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
1379+
dim, maskBox, identity, ordered);
1380+
builder.create<fir::CallOp>(loc, func, args);
1381+
}
1382+
1383+
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
1384+
/// that does not take DIM argument and return a scalar result.
13231385
mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
13241386
mlir::Location loc, mlir::Value arrayBox,
13251387
mlir::Value operation, mlir::Value maskBox,
1326-
mlir::Value identity, mlir::Value ordered,
1327-
mlir::Value resultBox) {
1388+
mlir::Value identity, mlir::Value ordered) {
13281389
mlir::func::FuncOp func;
13291390
auto ty = arrayBox.getType();
13301391
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
@@ -1334,6 +1395,10 @@ mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
13341395
mlir::MLIRContext *ctx = builder.getContext();
13351396
fir::factory::CharacterExprHelper charHelper{builder, loc};
13361397

1398+
assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) ||
1399+
mlir::isa<fir::LogicalType>(eleTy)) &&
1400+
"expect real, interger or logical");
1401+
13371402
if (eleTy.isF16())
13381403
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2)>(loc, builder);
13391404
else if (eleTy.isBF16())
@@ -1356,22 +1421,6 @@ mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
13561421
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8)>(loc, builder);
13571422
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
13581423
func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16>(loc, builder);
1359-
else if (eleTy == fir::ComplexType::get(ctx, 2))
1360-
func =
1361-
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2)>(loc, builder);
1362-
else if (eleTy == fir::ComplexType::get(ctx, 3))
1363-
func =
1364-
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3)>(loc, builder);
1365-
else if (eleTy == fir::ComplexType::get(ctx, 4))
1366-
func =
1367-
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4)>(loc, builder);
1368-
else if (eleTy == fir::ComplexType::get(ctx, 8))
1369-
func =
1370-
fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8)>(loc, builder);
1371-
else if (eleTy == fir::ComplexType::get(ctx, 10))
1372-
func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10>(loc, builder);
1373-
else if (eleTy == fir::ComplexType::get(ctx, 16))
1374-
func = fir::runtime::getRuntimeFunc<ForcedSumComplex16>(loc, builder);
13751424
else if (eleTy == fir::LogicalType::get(ctx, 1))
13761425
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1)>(loc, builder);
13771426
else if (eleTy == fir::LogicalType::get(ctx, 2))
@@ -1380,33 +1429,11 @@ mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
13801429
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4)>(loc, builder);
13811430
else if (eleTy == fir::LogicalType::get(ctx, 8))
13821431
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8)>(loc, builder);
1383-
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
1384-
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);
1385-
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
1386-
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);
1387-
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
1388-
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar4)>(loc, builder);
1389-
else if (fir::isa_derived(eleTy))
1390-
func =
1391-
fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);
13921432
else
13931433
fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
13941434

13951435
auto fTy = func.getFunctionType();
13961436
auto sourceFile = fir::factory::locationToFilename(builder, loc);
1397-
if (fir::isa_complex(eleTy) || fir::isa_char(eleTy) ||
1398-
fir::isa_derived(eleTy)) {
1399-
auto sourceLine =
1400-
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
1401-
auto opAddr =
1402-
builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
1403-
auto args = fir::runtime::createArguments(
1404-
builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
1405-
dim, maskBox, identity, ordered);
1406-
builder.create<fir::CallOp>(loc, func, args);
1407-
return resultBox;
1408-
}
1409-
14101437
auto sourceLine =
14111438
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
14121439
auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(1), operation);

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,8 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
14321432
mlir::LogicalResult fir::ConvertOp::verify() {
14331433
if (canBeConverted(getValue().getType(), getType()))
14341434
return mlir::success();
1435-
return emitOpError("invalid type conversion");
1435+
return emitOpError("invalid type conversion")
1436+
<< getValue().getType() << " / " << getType();
14361437
}
14371438

14381439
//===----------------------------------------------------------------------===//

flang/test/Lower/Intrinsics/reduce.f90

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ subroutine integer1(a, id)
2222

2323
res = reduce(a, red_int1, identity=id)
2424

25-
res = reduce(a, red_int1, identity=id, ordered = .false.)
25+
res = reduce(a, red_int1, identity=id, ordered = .true.)
2626

2727
res = reduce(a, red_int1, [.true., .true., .false.])
2828
end subroutine
@@ -40,21 +40,21 @@ subroutine integer1(a, id)
4040
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_PROC]] : (!fir.boxproc<() -> ()>) -> ((!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>)
4141
! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]]#1 : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
4242
! CHECK: %[[MASK_NONE:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
43-
! CHECK: %[[REDUCE_RES:.*]] = fir.call @_FortranAReduceInteger1(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[IDENTITY]], %true) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
43+
! CHECK: %[[REDUCE_RES:.*]] = fir.call @_FortranAReduceInteger1(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[IDENTITY]], %false) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
4444
! CHECK: hlfir.assign %[[REDUCE_RES]] to %[[RES]]#0 : i8, !fir.ref<i8>
4545
! CHECK: %[[ADDR_OP:.*]] = fir.address_of(@_QMreduce_modPred_int1) : (!fir.ref<i8>, !fir.ref<i8>) -> i8
4646
! CHECK: %[[BOX_PROC:.*]] = fir.emboxproc %[[ADDR_OP]] : ((!fir.ref<i8>, !fir.ref<i8>) -> i8) -> !fir.boxproc<() -> ()>
4747
! CHECK: %[[MASK:.*]] = fir.absent !fir.box<i1>
4848
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_PROC]] : (!fir.boxproc<() -> ()>) -> ((!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>)
4949
! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]]#1 : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
5050
! CHECK: %[[MASK_NONE:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
51-
! CHECK: %{{.*}} = fir.call @_FortranAReduceInteger1(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[ID]]#1, %true{{.*}}) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
52-
! CHECK: fir.call @_FortranAReduceInteger1(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}#1, %false)
51+
! CHECK: %{{.*}} = fir.call @_FortranAReduceInteger1(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[ID]]#1, %false{{.*}}) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
52+
! CHECK: fir.call @_FortranAReduceInteger1(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}#1, %true)
5353
! CHECK: %[[MASK:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3xl4.0"} : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.ref<!fir.array<3x!fir.logical<4>>>)
5454
! CHECK: %[[SHAPE_C3:.*]] = fir.shape %c3{{.*}} : (index) -> !fir.shape<1>
5555
! CHECK: %[[BOXED_MASK:.*]] = fir.embox %[[MASK]]#1(%[[SHAPE_C3]]) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<3x!fir.logical<4>>>
5656
! CHECK: %[[CONV_MASK:.*]] = fir.convert %[[BOXED_MASK]] : (!fir.box<!fir.array<3x!fir.logical<4>>>) -> !fir.box<none>
57-
! CHECK: fir.call @_FortranAReduceInteger1(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[CONV_MASK]], %{{.*}}, %true{{.*}})
57+
! CHECK: fir.call @_FortranAReduceInteger1(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[CONV_MASK]], %{{.*}}, %false{{.*}})
5858

5959
pure function red_int2(a,b)
6060
integer(2), intent(in) :: a, b
@@ -261,9 +261,25 @@ pure function red_complex10(a,b)
261261
subroutine complex10(a)
262262
complex(10), intent(in) :: a(:)
263263
complex(10) :: res
264-
! res = reduce(a, red_complex10)
264+
res = reduce(a, red_complex10)
265265
end subroutine
266266

267+
! CHECK: fir.call @_FortranACppReduceComplex10
268+
269+
pure function red_complex16(a,b)
270+
complex(16), intent(in) :: a, b
271+
complex(16) :: red_complex16
272+
red_complex16 = a + b
273+
end function
274+
275+
subroutine complex16(a)
276+
complex(16), intent(in) :: a(:)
277+
complex(16) :: res
278+
res = reduce(a, red_complex16)
279+
end subroutine
280+
281+
! CHECK: fir.call @_FortranACppReduceComplex16
282+
267283
pure function red_log1(a,b)
268284
logical(1), intent(in) :: a, b
269285
logical(1) :: red_log1

0 commit comments

Comments
 (0)