Skip to content

Commit 286c3b5

Browse files
authored
[flang] Enable REAL(16) MODULO lowering. (#85005)
The lowering currently relies on the trivial operations, so we should just lower it for REAL(16) the same way we do this for other trivial operations.
1 parent e0738cc commit 286c3b5

File tree

2 files changed

+52
-35
lines changed

2 files changed

+52
-35
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5208,6 +5208,8 @@ mlir::Value IntrinsicLibrary::genMod(mlir::Type resultType,
52085208
// MODULO
52095209
mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
52105210
llvm::ArrayRef<mlir::Value> args) {
5211+
// TODO: we'd better generate a runtime call here, when runtime error
5212+
// checking is needed (to detect 0 divisor) or when precise math is requested.
52115213
assert(args.size() == 2);
52125214
// No floored modulo op in LLVM/MLIR yet. TODO: add one to MLIR.
52135215
// In the meantime, use a simple inlined implementation based on truncated
@@ -5233,10 +5235,7 @@ mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
52335235
return builder.create<mlir::arith::SelectOp>(loc, mustAddP, remPlusP,
52345236
remainder);
52355237
}
5236-
// Real case
5237-
if (resultType == mlir::FloatType::getF128(builder.getContext()))
52385238

5239-
TODO(loc, "REAL(KIND=16): in MODULO intrinsic");
52405239
auto remainder = builder.create<mlir::arith::RemFOp>(loc, args[0], args[1]);
52415240
mlir::Value zero = builder.createRealZeroConstant(loc, remainder.getType());
52425241
auto remainderIsNotZero = builder.create<mlir::arith::CmpFOp>(

flang/test/Lower/Intrinsics/modulo.f90

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,54 @@
33
! CHECK-LABEL: func @_QPmodulo_testr(
44
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<f64>{{.*}}, %[[arg1:.*]]: !fir.ref<f64>{{.*}}, %[[arg2:.*]]: !fir.ref<f64>{{.*}}) {
55
subroutine modulo_testr(r, a, p)
6-
real(8) :: r, a, p
7-
! CHECK-DAG: %[[a:.*]] = fir.load %[[arg1]] : !fir.ref<f64>
8-
! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
9-
! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
10-
! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
11-
! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
12-
! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
13-
! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
14-
! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
15-
! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
16-
! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
17-
! CHECK: %[[res:.*]] = arith.select %[[mustAddP]], %[[remPlusP]], %[[rem]] : f64
18-
! CHECK: fir.store %[[res]] to %[[arg0]] : !fir.ref<f64>
19-
r = modulo(a, p)
20-
end subroutine
21-
22-
! CHECK-LABEL: func @_QPmodulo_testi(
23-
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i64>{{.*}}, %[[arg1:.*]]: !fir.ref<i64>{{.*}}, %[[arg2:.*]]: !fir.ref<i64>{{.*}}) {
24-
subroutine modulo_testi(r, a, p)
25-
integer(8) :: r, a, p
26-
! CHECK-DAG: %[[a:.*]] = fir.load %[[arg1]] : !fir.ref<i64>
27-
! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<i64>
28-
! CHECK-DAG: %[[rem:.*]] = arith.remsi %[[a]], %[[p]] : i64
29-
! CHECK-DAG: %[[argXor:.*]] = arith.xori %[[a]], %[[p]] : i64
30-
! CHECK-DAG: %[[signDifferent:.*]] = arith.cmpi slt, %[[argXor]], %c0{{.*}} : i64
31-
! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpi ne, %[[rem]], %c0{{.*}} : i64
32-
! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
33-
! CHECK-DAG: %[[remPlusP:.*]] = arith.addi %[[rem]], %[[p]] : i64
34-
! CHECK: %[[res:.*]] = arith.select %[[mustAddP]], %[[remPlusP]], %[[rem]] : i64
35-
! CHECK: fir.store %[[res]] to %[[arg0]] : !fir.ref<i64>
36-
r = modulo(a, p)
37-
end subroutine
6+
real(8) :: r, a, p
7+
! CHECK-DAG: %[[a:.*]] = fir.load %[[arg1]] : !fir.ref<f64>
8+
! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
9+
! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
10+
! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
11+
! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
12+
! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
13+
! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
14+
! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
15+
! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
16+
! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
17+
! CHECK: %[[res:.*]] = arith.select %[[mustAddP]], %[[remPlusP]], %[[rem]] : f64
18+
! CHECK: fir.store %[[res]] to %[[arg0]] : !fir.ref<f64>
19+
r = modulo(a, p)
20+
end subroutine
3821

22+
! CHECK-LABEL: func @_QPmodulo_testi(
23+
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i64>{{.*}}, %[[arg1:.*]]: !fir.ref<i64>{{.*}}, %[[arg2:.*]]: !fir.ref<i64>{{.*}}) {
24+
subroutine modulo_testi(r, a, p)
25+
integer(8) :: r, a, p
26+
! CHECK-DAG: %[[a:.*]] = fir.load %[[arg1]] : !fir.ref<i64>
27+
! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<i64>
28+
! CHECK-DAG: %[[rem:.*]] = arith.remsi %[[a]], %[[p]] : i64
29+
! CHECK-DAG: %[[argXor:.*]] = arith.xori %[[a]], %[[p]] : i64
30+
! CHECK-DAG: %[[signDifferent:.*]] = arith.cmpi slt, %[[argXor]], %c0{{.*}} : i64
31+
! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpi ne, %[[rem]], %c0{{.*}} : i64
32+
! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
33+
! CHECK-DAG: %[[remPlusP:.*]] = arith.addi %[[rem]], %[[p]] : i64
34+
! CHECK: %[[res:.*]] = arith.select %[[mustAddP]], %[[remPlusP]], %[[rem]] : i64
35+
! CHECK: fir.store %[[res]] to %[[arg0]] : !fir.ref<i64>
36+
r = modulo(a, p)
37+
end subroutine
38+
39+
! CHECK-LABEL: func @_QPmodulo_testr16(
40+
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<f128>{{.*}}, %[[arg1:.*]]: !fir.ref<f128>{{.*}}, %[[arg2:.*]]: !fir.ref<f128>{{.*}}) {
41+
subroutine modulo_testr16(r, a, p)
42+
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>
55+
r = modulo(a, p)
56+
end subroutine

0 commit comments

Comments
 (0)