1 | //===- NumericTest.cpp -- Numeric intrinsic runtime builder unit tests ----===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "flang/Optimizer/Builder/Runtime/Numeric.h" |
10 | #include "RuntimeCallTestBase.h" |
11 | #include "gtest/gtest.h" |
12 | |
13 | using namespace mlir; |
14 | |
15 | void testGenExponent(fir::FirOpBuilder &builder, mlir::Type resultType, |
16 | mlir::Type xType, llvm::StringRef fctName) { |
17 | auto loc = builder.getUnknownLoc(); |
18 | mlir::Value x = builder.create<fir::UndefOp>(loc, xType); |
19 | mlir::Value exp = fir::runtime::genExponent(builder, loc, resultType, x); |
20 | checkCallOp(exp.getDefiningOp(), fctName, 1, /*addLocArg=*/false); |
21 | } |
22 | |
23 | TEST_F(RuntimeCallTest, genExponentTest) { |
24 | testGenExponent(*firBuilder, i32Ty, f32Ty, "_FortranAExponent4_4" ); |
25 | testGenExponent(*firBuilder, i64Ty, f32Ty, "_FortranAExponent4_8" ); |
26 | testGenExponent(*firBuilder, i32Ty, f64Ty, "_FortranAExponent8_4" ); |
27 | testGenExponent(*firBuilder, i64Ty, f64Ty, "_FortranAExponent8_8" ); |
28 | testGenExponent(*firBuilder, i32Ty, f80Ty, "_FortranAExponent10_4" ); |
29 | testGenExponent(*firBuilder, i64Ty, f80Ty, "_FortranAExponent10_8" ); |
30 | testGenExponent(*firBuilder, i32Ty, f128Ty, "_FortranAExponent16_4" ); |
31 | testGenExponent(*firBuilder, i64Ty, f128Ty, "_FortranAExponent16_8" ); |
32 | } |
33 | |
34 | void testGenX(fir::FirOpBuilder &builder, mlir::Type xType, |
35 | mlir::Value (*genFct)(fir::FirOpBuilder &, Location, mlir::Value), |
36 | llvm::StringRef fctName) { |
37 | auto loc = builder.getUnknownLoc(); |
38 | mlir::Value x = builder.create<fir::UndefOp>(loc, xType); |
39 | mlir::Value val = genFct(builder, loc, x); |
40 | checkCallOp(val.getDefiningOp(), fctName, 1, /*addLocArg=*/false); |
41 | } |
42 | |
43 | TEST_F(RuntimeCallTest, genFractionTest) { |
44 | testGenX(*firBuilder, f32Ty, fir::runtime::genFraction, "_FortranAFraction4" ); |
45 | testGenX(*firBuilder, f64Ty, fir::runtime::genFraction, "_FortranAFraction8" ); |
46 | testGenX( |
47 | *firBuilder, f80Ty, fir::runtime::genFraction, "_FortranAFraction10" ); |
48 | testGenX( |
49 | *firBuilder, f128Ty, fir::runtime::genFraction, "_FortranAFraction16" ); |
50 | } |
51 | |
52 | void testGenNearest(fir::FirOpBuilder &builder, mlir::Type xType, |
53 | mlir::Type sType, llvm::StringRef fctName) { |
54 | auto loc = builder.getUnknownLoc(); |
55 | mlir::Value x = builder.create<fir::UndefOp>(loc, xType); |
56 | mlir::Value s = builder.create<fir::UndefOp>(loc, sType); |
57 | mlir::Value nearest = fir::runtime::genNearest(builder, loc, x, s); |
58 | checkCallOp(nearest.getDefiningOp(), fctName, 2, /*addLocArg=*/false); |
59 | auto callOp = mlir::dyn_cast<fir::CallOp>(nearest.getDefiningOp()); |
60 | mlir::Value select = callOp.getOperands()[1]; |
61 | EXPECT_TRUE(mlir::isa<mlir::arith::SelectOp>(select.getDefiningOp())); |
62 | auto selectOp = mlir::dyn_cast<mlir::arith::SelectOp>(select.getDefiningOp()); |
63 | mlir::Value cmp = selectOp.getCondition(); |
64 | EXPECT_TRUE(mlir::isa<mlir::arith::CmpFOp>(cmp.getDefiningOp())); |
65 | auto cmpOp = mlir::dyn_cast<mlir::arith::CmpFOp>(cmp.getDefiningOp()); |
66 | EXPECT_EQ(s, cmpOp.getLhs()); |
67 | } |
68 | |
69 | TEST_F(RuntimeCallTest, genNearestTest) { |
70 | testGenNearest(*firBuilder, f32Ty, f32Ty, "_FortranANearest4" ); |
71 | testGenNearest(*firBuilder, f64Ty, f32Ty, "_FortranANearest8" ); |
72 | testGenNearest(*firBuilder, f80Ty, f32Ty, "_FortranANearest10" ); |
73 | testGenNearest(*firBuilder, f128Ty, f32Ty, "_FortranANearest16" ); |
74 | } |
75 | |
76 | TEST_F(RuntimeCallTest, genRRSpacingTest) { |
77 | testGenX( |
78 | *firBuilder, f32Ty, fir::runtime::genRRSpacing, "_FortranARRSpacing4" ); |
79 | testGenX( |
80 | *firBuilder, f64Ty, fir::runtime::genRRSpacing, "_FortranARRSpacing8" ); |
81 | testGenX( |
82 | *firBuilder, f80Ty, fir::runtime::genRRSpacing, "_FortranARRSpacing10" ); |
83 | testGenX( |
84 | *firBuilder, f128Ty, fir::runtime::genRRSpacing, "_FortranARRSpacing16" ); |
85 | } |
86 | |
87 | void testGenXI(fir::FirOpBuilder &builder, mlir::Type xType, mlir::Type iType, |
88 | mlir::Value (*genFct)( |
89 | fir::FirOpBuilder &, Location, mlir::Value, mlir::Value), |
90 | llvm::StringRef fctName) { |
91 | auto loc = builder.getUnknownLoc(); |
92 | mlir::Value x = builder.create<fir::UndefOp>(loc, xType); |
93 | mlir::Value i = builder.create<fir::UndefOp>(loc, iType); |
94 | mlir::Value val = genFct(builder, loc, x, i); |
95 | checkCallOp(val.getDefiningOp(), fctName, 2, /*addLocArg=*/false); |
96 | } |
97 | |
98 | TEST_F(RuntimeCallTest, genScaleTest) { |
99 | testGenXI( |
100 | *firBuilder, f32Ty, f32Ty, fir::runtime::genScale, "_FortranAScale4" ); |
101 | testGenXI( |
102 | *firBuilder, f64Ty, f32Ty, fir::runtime::genScale, "_FortranAScale8" ); |
103 | testGenXI( |
104 | *firBuilder, f80Ty, f32Ty, fir::runtime::genScale, "_FortranAScale10" ); |
105 | testGenXI( |
106 | *firBuilder, f128Ty, f32Ty, fir::runtime::genScale, "_FortranAScale16" ); |
107 | } |
108 | |
109 | TEST_F(RuntimeCallTest, genSetExponentTest) { |
110 | testGenXI(*firBuilder, f32Ty, f32Ty, fir::runtime::genSetExponent, |
111 | "_FortranASetExponent4" ); |
112 | testGenXI(*firBuilder, f64Ty, f32Ty, fir::runtime::genSetExponent, |
113 | "_FortranASetExponent8" ); |
114 | testGenXI(*firBuilder, f80Ty, f32Ty, fir::runtime::genSetExponent, |
115 | "_FortranASetExponent10" ); |
116 | testGenXI(*firBuilder, f128Ty, f32Ty, fir::runtime::genSetExponent, |
117 | "_FortranASetExponent16" ); |
118 | } |
119 | |
120 | TEST_F(RuntimeCallTest, genSpacingTest) { |
121 | testGenX(*firBuilder, f32Ty, fir::runtime::genSpacing, "_FortranASpacing4" ); |
122 | testGenX(*firBuilder, f64Ty, fir::runtime::genSpacing, "_FortranASpacing8" ); |
123 | testGenX(*firBuilder, f80Ty, fir::runtime::genSpacing, "_FortranASpacing10" ); |
124 | testGenX(*firBuilder, f128Ty, fir::runtime::genSpacing, "_FortranASpacing16" ); |
125 | } |
126 | |