Skip to content

Commit 86293a7

Browse files
authored
[flang] Lower REAL(16) MODULO to Float128Math library call. (#85322)
I did not test it through in #85005, and my assumption was wrong: arith::RemFOp might be lowered to an fmodf128() call that does not exist everywhere.
1 parent ec2b752 commit 86293a7

File tree

4 files changed

+53
-12
lines changed

4 files changed

+53
-12
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ mlir::Value genFraction(fir::FirOpBuilder &builder, mlir::Location loc,
3030
mlir::Value genMod(fir::FirOpBuilder &builder, mlir::Location loc,
3131
mlir::Value a, mlir::Value p);
3232

33+
/// Generate call to Modulo intrinsic runtime routine.
34+
mlir::Value genModulo(fir::FirOpBuilder &builder, mlir::Location loc,
35+
mlir::Value a, mlir::Value p);
36+
3337
/// Generate call to Nearest intrinsic runtime routine.
3438
mlir::Value genNearest(fir::FirOpBuilder &builder, mlir::Location loc,
3539
mlir::Value x, mlir::Value s);

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5259,6 +5259,13 @@ mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
52595259
remainder);
52605260
}
52615261

5262+
// F128 arith::RemFOp may be lowered to a runtime call that may be unsupported
5263+
// on the target, so generate a call to Fortran Runtime's ModuloReal16.
5264+
if (resultType == mlir::FloatType::getF128(builder.getContext()))
5265+
return builder.createConvert(
5266+
loc, resultType,
5267+
fir::runtime::genModulo(builder, loc, args[0], args[1]));
5268+
52625269
auto remainder = builder.create<mlir::arith::RemFOp>(loc, args[0], args[1]);
52635270
mlir::Value zero = builder.createRealZeroConstant(loc, remainder.getType());
52645271
auto remainderIsNotZero = builder.create<mlir::arith::CmpFOp>(

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ struct ForcedMod16 {
118118
}
119119
};
120120

121+
/// Placeholder for real*16 version of Modulo Intrinsic
122+
struct ForcedModulo16 {
123+
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ModuloReal16));
124+
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
125+
return [](mlir::MLIRContext *ctx) {
126+
auto fltTy = mlir::FloatType::getF128(ctx);
127+
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
128+
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
129+
return mlir::FunctionType::get(ctx, {fltTy, fltTy, strTy, intTy},
130+
{fltTy});
131+
};
132+
}
133+
};
134+
121135
/// Placeholder for real*10 version of Nearest Intrinsic
122136
struct ForcedNearest10 {
123137
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Nearest10));
@@ -323,6 +337,33 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
323337
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
324338
}
325339

340+
/// Generate call to Modulo intrinsic runtime routine.
341+
mlir::Value fir::runtime::genModulo(fir::FirOpBuilder &builder,
342+
mlir::Location loc, mlir::Value a,
343+
mlir::Value p) {
344+
mlir::func::FuncOp func;
345+
mlir::Type fltTy = a.getType();
346+
347+
if (fltTy != p.getType())
348+
fir::emitFatalError(loc, "arguments type mismatch in MOD");
349+
350+
// MODULO is lowered into math operations in intrinsics lowering,
351+
// so genModulo() should only be used for F128 data type now.
352+
if (fltTy.isF128())
353+
func = fir::runtime::getRuntimeFunc<ForcedModulo16>(loc, builder);
354+
else
355+
fir::intrinsicTypeTODO(builder, fltTy, loc, "MODULO");
356+
357+
auto funcTy = func.getFunctionType();
358+
auto sourceFile = fir::factory::locationToFilename(builder, loc);
359+
auto sourceLine =
360+
fir::factory::locationToLineNo(builder, loc, funcTy.getInput(3));
361+
auto args = fir::runtime::createArguments(builder, loc, funcTy, a, p,
362+
sourceFile, sourceLine);
363+
364+
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
365+
}
366+
326367
/// Generate call to Nearest intrinsic runtime routine.
327368
mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
328369
mlir::Location loc, mlir::Value x,

flang/test/Lower/Intrinsics/modulo.f90

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,6 @@ subroutine modulo_testi(r, a, p)
4040
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<f128>{{.*}}, %[[arg1:.*]]: !fir.ref<f128>{{.*}}, %[[arg2:.*]]: !fir.ref<f128>{{.*}}) {
4141
subroutine modulo_testr16(r, a, p)
4242
real(16) :: r, a, p
43-
! CHECK-DAG: %[[a:.*]] = fir.load %[[arg1]] : !fir.ref<f128>
44-
! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f128>
45-
! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f128
46-
! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f128
47-
! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f128
48-
! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f128
49-
! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f128
50-
! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
51-
! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
52-
! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f128
53-
! CHECK: %[[res:.*]] = arith.select %[[mustAddP]], %[[remPlusP]], %[[rem]] : f128
54-
! CHECK: fir.store %[[res]] to %[[arg0]] : !fir.ref<f128>
43+
! CHECK: fir.call @_FortranAModuloReal16({{.*}}){{.*}}: (f128, f128, !fir.ref<i8>, i32) -> f128
5544
r = modulo(a, p)
5645
end subroutine

0 commit comments

Comments
 (0)