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