Skip to content

Commit e771da8

Browse files
wsmosesjeanPerier
authored andcommitted
Handle more LLVM math functions and permit old flang abi as option (#775)
1 parent 79a86aa commit e771da8

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,16 @@ static mlir::FunctionType genF64F64FuncType(mlir::MLIRContext *context) {
715715
return mlir::FunctionType::get(context, {t}, {t});
716716
}
717717

718+
static mlir::FunctionType genF32F32F32FuncType(mlir::MLIRContext *context) {
719+
auto t = mlir::FloatType::getF32(context);
720+
return mlir::FunctionType::get(context, {t, t}, {t});
721+
}
722+
723+
static mlir::FunctionType genF64F64F64FuncType(mlir::MLIRContext *context) {
724+
auto t = mlir::FloatType::getF64(context);
725+
return mlir::FunctionType::get(context, {t, t}, {t});
726+
}
727+
718728
template <int Bits>
719729
static mlir::FunctionType genIntF64FuncType(mlir::MLIRContext *context) {
720730
auto t = mlir::FloatType::getF64(context);
@@ -739,11 +749,17 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
739749
{"aint", "llvm.trunc.f64", genF64F64FuncType},
740750
{"anint", "llvm.round.f32", genF32F32FuncType},
741751
{"anint", "llvm.round.f64", genF64F64FuncType},
752+
{"atan", "atanf", genF32F32FuncType},
753+
{"atan", "atan", genF64F64FuncType},
742754
// ceil is used for CEILING but is different, it returns a real.
743755
{"ceil", "llvm.ceil.f32", genF32F32FuncType},
744756
{"ceil", "llvm.ceil.f64", genF64F64FuncType},
745757
{"cos", "llvm.cos.f32", genF32F32FuncType},
746758
{"cos", "llvm.cos.f64", genF64F64FuncType},
759+
{"cosh", "coshf", genF32F32FuncType},
760+
{"cosh", "cosh", genF64F64FuncType},
761+
{"exp", "llvm.exp.f32", genF32F32FuncType},
762+
{"exp", "llvm.exp.f64", genF64F64FuncType},
747763
// llvm.floor is used for FLOOR, but returns real.
748764
{"floor", "llvm.floor.f32", genF32F32FuncType},
749765
{"floor", "llvm.floor.f64", genF64F64FuncType},
@@ -755,8 +771,12 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
755771
{"nint", "llvm.lround.i64.f32", genIntF32FuncType<64>},
756772
{"nint", "llvm.lround.i32.f64", genIntF64FuncType<32>},
757773
{"nint", "llvm.lround.i32.f32", genIntF32FuncType<32>},
774+
{"pow", "llvm.pow.f32", genF32F32F32FuncType},
775+
{"pow", "llvm.pow.f64", genF64F64F64FuncType},
758776
{"sin", "llvm.sin.f32", genF32F32FuncType},
759777
{"sin", "llvm.sin.f64", genF64F64FuncType},
778+
{"sinh", "sinhf", genF32F32FuncType},
779+
{"sinh", "sinh", genF64F64FuncType},
760780
{"sqrt", "llvm.sqrt.f32", genF32F32FuncType},
761781
{"sqrt", "llvm.sqrt.f64", genF64F64FuncType},
762782
};

flang/test/Lower/llvm-math.f90

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
! RUN: bbc -emit-fir %s -o - --math-runtime=llvm | FileCheck %s
2+
3+
SUBROUTINE POW_WRAPPER(IN, IN2, OUT)
4+
DOUBLE PRECISION IN, IN2
5+
OUT = IN ** IN2
6+
RETURN
7+
END
8+
9+
! CHECK: func @_QPpow_wrapper(%arg0: !fir.ref<f64>, %arg1: !fir.ref<f64>, %arg2: !fir.ref<f32>)
10+
! CHECK-NEXT: %0 = fir.load %arg0 : !fir.ref<f64>
11+
! CHECK-NEXT: %1 = fir.load %arg1 : !fir.ref<f64>
12+
! CHECK-NEXT: %2 = fir.call @llvm.pow.f64(%0, %1) : (f64, f64) -> f64
13+
14+
SUBROUTINE POWF_WRAPPER(IN, IN2, OUT)
15+
REAL IN, IN2
16+
OUT = IN ** IN2
17+
RETURN
18+
END
19+
20+
! CHECK: func @_QPpowf_wrapper(%arg0: !fir.ref<f32>, %arg1: !fir.ref<f32>, %arg2: !fir.ref<f32>)
21+
! CHECK-NEXT: %0 = fir.load %arg0 : !fir.ref<f32>
22+
! CHECK-NEXT: %1 = fir.load %arg1 : !fir.ref<f32>
23+
! CHECK-NEXT: %2 = fir.call @llvm.pow.f32(%0, %1) : (f32, f32) -> f32
24+
25+
SUBROUTINE ATAN_WRAPPER(IN, OUT)
26+
DOUBLE PRECISION IN
27+
OUT = DATAN(IN)
28+
RETURN
29+
END
30+
31+
! CHECK: func private @fir.atan.f64.f64(%arg0: f64)
32+
! CHECK-NEXT: %0 = fir.call @atan(%arg0) : (f64) -> f64
33+
! CHECK-NEXT: return %0 : f64
34+
! CHECK-NEXT: }
35+
36+
SUBROUTINE EXP_WRAPPER(IN, OUT)
37+
DOUBLE PRECISION IN
38+
OUT = DEXP(IN)
39+
RETURN
40+
END
41+
42+
! CHECK: func private @fir.exp.f64.f64(%arg0: f64)
43+
! CHECK-NEXT: %0 = fir.call @llvm.exp.f64(%arg0) : (f64) -> f64
44+
! CHECK-NEXT: return %0 : f64
45+
! CHECK-NEXT: }
46+
47+
SUBROUTINE SINH_WRAPPER(IN, OUT)
48+
DOUBLE PRECISION IN
49+
OUT = DSINH(IN)
50+
RETURN
51+
END
52+
53+
! CHECK: func private @fir.sinh.f64.f64(%arg0: f64)
54+
! CHECK-NEXT: %0 = fir.call @sinh(%arg0) : (f64) -> f64
55+
! CHECK-NEXT: return %0 : f64
56+
! CHECK-NEXT: }
57+
58+
SUBROUTINE COSH_WRAPPER(IN, OUT)
59+
DOUBLE PRECISION IN
60+
OUT = DCOSH(IN)
61+
RETURN
62+
END
63+
64+
! CHECK: func private @fir.cosh.f64.f64(%arg0: f64)
65+
! CHECK-NEXT: %0 = fir.call @cosh(%arg0) : (f64) -> f64
66+
! CHECK-NEXT: return %0 : f64
67+
! CHECK-NEXT: }
68+
69+
70+
SUBROUTINE ATANF_WRAPPER(IN, OUT)
71+
REAL IN
72+
OUT = ATAN(IN)
73+
RETURN
74+
END
75+
76+
! CHECK: func private @fir.atan.f32.f32(%arg0: f32)
77+
! CHECK-NEXT: %0 = fir.call @atanf(%arg0) : (f32) -> f32
78+
! CHECK-NEXT: return %0 : f32
79+
! CHECK-NEXT: }
80+
81+
SUBROUTINE EXPF_WRAPPER(IN, OUT)
82+
REAL IN
83+
OUT = EXP(IN)
84+
RETURN
85+
END
86+
87+
! CHECK: func private @fir.exp.f32.f32(%arg0: f32)
88+
! CHECK-NEXT: %0 = fir.call @llvm.exp.f32(%arg0) : (f32) -> f32
89+
! CHECK-NEXT: return %0 : f32
90+
! CHECK-NEXT: }
91+
92+
SUBROUTINE SINHF_WRAPPER(IN, OUT)
93+
REAL IN
94+
OUT = SINH(IN)
95+
RETURN
96+
END
97+
98+
! CHECK: func private @fir.sinh.f32.f32(%arg0: f32)
99+
! CHECK-NEXT: %0 = fir.call @sinhf(%arg0) : (f32) -> f32
100+
! CHECK-NEXT: return %0 : f32
101+
! CHECK-NEXT: }
102+
103+
SUBROUTINE COSHF_WRAPPER(IN, OUT)
104+
REAL IN
105+
OUT = COSH(IN)
106+
RETURN
107+
END
108+
109+
! CHECK: func private @fir.cosh.f32.f32(%arg0: f32)
110+
! CHECK-NEXT: %0 = fir.call @coshf(%arg0) : (f32) -> f32
111+
! CHECK-NEXT: return %0 : f32
112+
! CHECK-NEXT: }
113+

0 commit comments

Comments
 (0)