392 lines · cpp
1//===- ReductionTest.cpp -- Reduction 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Optimizer/Builder/Runtime/Reduction.h"10#include "RuntimeCallTestBase.h"11#include "gtest/gtest.h"12 13TEST_F(RuntimeCallTest, genAllTest) {14 mlir::Location loc = firBuilder->getUnknownLoc();15 mlir::Value undef = fir::UndefOp::create(*firBuilder, loc, seqTy10);16 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);17 mlir::Value all = fir::runtime::genAll(*firBuilder, loc, undef, dim);18 checkCallOp(all.getDefiningOp(), "_FortranAAll", 2);19}20 21TEST_F(RuntimeCallTest, genAllDescriptorTest) {22 mlir::Location loc = firBuilder->getUnknownLoc();23 mlir::Value result = fir::UndefOp::create(*firBuilder, loc, seqTy10);24 mlir::Value mask = fir::UndefOp::create(*firBuilder, loc, seqTy10);25 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);26 fir::runtime::genAllDescriptor(*firBuilder, loc, result, mask, dim);27 checkCallOpFromResultBox(result, "_FortranAAllDim", 3);28}29 30TEST_F(RuntimeCallTest, genAnyTest) {31 mlir::Location loc = firBuilder->getUnknownLoc();32 mlir::Value undef = fir::UndefOp::create(*firBuilder, loc, seqTy10);33 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);34 mlir::Value any = fir::runtime::genAny(*firBuilder, loc, undef, dim);35 checkCallOp(any.getDefiningOp(), "_FortranAAny", 2);36}37 38TEST_F(RuntimeCallTest, genAnyDescriptorTest) {39 mlir::Location loc = firBuilder->getUnknownLoc();40 mlir::Value result = fir::UndefOp::create(*firBuilder, loc, seqTy10);41 mlir::Value mask = fir::UndefOp::create(*firBuilder, loc, seqTy10);42 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);43 fir::runtime::genAnyDescriptor(*firBuilder, loc, result, mask, dim);44 checkCallOpFromResultBox(result, "_FortranAAnyDim", 3);45}46 47TEST_F(RuntimeCallTest, genCountTest) {48 mlir::Location loc = firBuilder->getUnknownLoc();49 mlir::Value undef = fir::UndefOp::create(*firBuilder, loc, seqTy10);50 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);51 mlir::Value count = fir::runtime::genCount(*firBuilder, loc, undef, dim);52 checkCallOp(count.getDefiningOp(), "_FortranACount", 2);53}54 55TEST_F(RuntimeCallTest, genCountDimTest) {56 mlir::Location loc = firBuilder->getUnknownLoc();57 mlir::Value result = fir::UndefOp::create(*firBuilder, loc, seqTy10);58 mlir::Value mask = fir::UndefOp::create(*firBuilder, loc, seqTy10);59 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);60 mlir::Value kind = firBuilder->createIntegerConstant(loc, i32Ty, 1);61 fir::runtime::genCountDim(*firBuilder, loc, result, mask, dim, kind);62 checkCallOpFromResultBox(result, "_FortranACountDim", 4);63}64 65void testGenMaxVal(66 fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {67 mlir::Location loc = builder.getUnknownLoc();68 mlir::Type seqTy =69 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);70 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);71 mlir::Value undef = fir::UndefOp::create(builder, loc, refSeqTy);72 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);73 mlir::Value max = fir::runtime::genMaxval(builder, loc, undef, mask);74 checkCallOp(max.getDefiningOp(), fctName, 3);75}76 77TEST_F(RuntimeCallTest, genMaxValTest) {78 testGenMaxVal(*firBuilder, f32Ty, "_FortranAMaxvalReal4");79 testGenMaxVal(*firBuilder, f64Ty, "_FortranAMaxvalReal8");80 testGenMaxVal(*firBuilder, f80Ty, "_FortranAMaxvalReal10");81 testGenMaxVal(*firBuilder, f128Ty, "_FortranAMaxvalReal16");82 83 testGenMaxVal(*firBuilder, i8Ty, "_FortranAMaxvalInteger1");84 testGenMaxVal(*firBuilder, i16Ty, "_FortranAMaxvalInteger2");85 testGenMaxVal(*firBuilder, i32Ty, "_FortranAMaxvalInteger4");86 testGenMaxVal(*firBuilder, i64Ty, "_FortranAMaxvalInteger8");87 testGenMaxVal(*firBuilder, i128Ty, "_FortranAMaxvalInteger16");88}89 90void testGenMinVal(91 fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {92 mlir::Location loc = builder.getUnknownLoc();93 mlir::Type seqTy =94 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);95 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);96 mlir::Value undef = fir::UndefOp::create(builder, loc, refSeqTy);97 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);98 mlir::Value min = fir::runtime::genMinval(builder, loc, undef, mask);99 checkCallOp(min.getDefiningOp(), fctName, 3);100}101 102TEST_F(RuntimeCallTest, genMinValTest) {103 testGenMinVal(*firBuilder, f32Ty, "_FortranAMinvalReal4");104 testGenMinVal(*firBuilder, f64Ty, "_FortranAMinvalReal8");105 testGenMinVal(*firBuilder, f80Ty, "_FortranAMinvalReal10");106 testGenMinVal(*firBuilder, f128Ty, "_FortranAMinvalReal16");107 108 testGenMinVal(*firBuilder, i8Ty, "_FortranAMinvalInteger1");109 testGenMinVal(*firBuilder, i16Ty, "_FortranAMinvalInteger2");110 testGenMinVal(*firBuilder, i32Ty, "_FortranAMinvalInteger4");111 testGenMinVal(*firBuilder, i64Ty, "_FortranAMinvalInteger8");112 testGenMinVal(*firBuilder, i128Ty, "_FortranAMinvalInteger16");113}114 115TEST_F(RuntimeCallTest, genParityTest) {116 mlir::Location loc = firBuilder->getUnknownLoc();117 mlir::Value undef = fir::UndefOp::create(*firBuilder, loc, seqTy10);118 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);119 mlir::Value parity = fir::runtime::genParity(*firBuilder, loc, undef, dim);120 checkCallOp(parity.getDefiningOp(), "_FortranAParity", 2);121}122 123TEST_F(RuntimeCallTest, genParityDescriptorTest) {124 mlir::Location loc = firBuilder->getUnknownLoc();125 mlir::Value result = fir::UndefOp::create(*firBuilder, loc, seqTy10);126 mlir::Value mask = fir::UndefOp::create(*firBuilder, loc, seqTy10);127 mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);128 fir::runtime::genParityDescriptor(*firBuilder, loc, result, mask, dim);129 checkCallOpFromResultBox(result, "_FortranAParityDim", 3);130}131 132void testGenSum(133 fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {134 mlir::Location loc = builder.getUnknownLoc();135 mlir::Type seqTy =136 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);137 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);138 mlir::Value undef = fir::UndefOp::create(builder, loc, refSeqTy);139 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);140 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);141 mlir::Value sum = fir::runtime::genSum(builder, loc, undef, mask, result);142 if (fir::isa_complex(eleTy))143 checkCallOpFromResultBox(result, fctName, 4);144 else145 checkCallOp(sum.getDefiningOp(), fctName, 3);146}147 148TEST_F(RuntimeCallTest, genSumTest) {149 testGenSum(*firBuilder, f32Ty, "_FortranASumReal4");150 testGenSum(*firBuilder, f64Ty, "_FortranASumReal8");151 testGenSum(*firBuilder, f80Ty, "_FortranASumReal10");152 testGenSum(*firBuilder, f128Ty, "_FortranASumReal16");153 testGenSum(*firBuilder, i8Ty, "_FortranASumInteger1");154 testGenSum(*firBuilder, i16Ty, "_FortranASumInteger2");155 testGenSum(*firBuilder, i32Ty, "_FortranASumInteger4");156 testGenSum(*firBuilder, i64Ty, "_FortranASumInteger8");157 testGenSum(*firBuilder, i128Ty, "_FortranASumInteger16");158 testGenSum(*firBuilder, c4Ty, "_FortranACppSumComplex4");159 testGenSum(*firBuilder, c8Ty, "_FortranACppSumComplex8");160 testGenSum(*firBuilder, c10Ty, "_FortranACppSumComplex10");161 testGenSum(*firBuilder, c16Ty, "_FortranACppSumComplex16");162}163 164void testGenProduct(165 fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {166 mlir::Location loc = builder.getUnknownLoc();167 mlir::Type seqTy =168 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);169 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);170 mlir::Value undef = fir::UndefOp::create(builder, loc, refSeqTy);171 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);172 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);173 mlir::Value prod =174 fir::runtime::genProduct(builder, loc, undef, mask, result);175 if (fir::isa_complex(eleTy))176 checkCallOpFromResultBox(result, fctName, 4);177 else178 checkCallOp(prod.getDefiningOp(), fctName, 3);179}180 181TEST_F(RuntimeCallTest, genProduct) {182 testGenProduct(*firBuilder, f32Ty, "_FortranAProductReal4");183 testGenProduct(*firBuilder, f64Ty, "_FortranAProductReal8");184 testGenProduct(*firBuilder, f80Ty, "_FortranAProductReal10");185 testGenProduct(*firBuilder, f128Ty, "_FortranAProductReal16");186 testGenProduct(*firBuilder, i8Ty, "_FortranAProductInteger1");187 testGenProduct(*firBuilder, i16Ty, "_FortranAProductInteger2");188 testGenProduct(*firBuilder, i32Ty, "_FortranAProductInteger4");189 testGenProduct(*firBuilder, i64Ty, "_FortranAProductInteger8");190 testGenProduct(*firBuilder, i128Ty, "_FortranAProductInteger16");191 testGenProduct(*firBuilder, c4Ty, "_FortranACppProductComplex4");192 testGenProduct(*firBuilder, c8Ty, "_FortranACppProductComplex8");193 testGenProduct(*firBuilder, c10Ty, "_FortranACppProductComplex10");194 testGenProduct(*firBuilder, c16Ty, "_FortranACppProductComplex16");195}196 197void testGenDotProduct(198 fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {199 mlir::Location loc = builder.getUnknownLoc();200 mlir::Type seqTy =201 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);202 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);203 mlir::Value a = fir::UndefOp::create(builder, loc, refSeqTy);204 mlir::Value b = fir::UndefOp::create(builder, loc, refSeqTy);205 mlir::Value result =206 fir::UndefOp::create(builder, loc, fir::ReferenceType::get(eleTy));207 mlir::Value prod = fir::runtime::genDotProduct(builder, loc, a, b, result);208 if (fir::isa_complex(eleTy))209 checkCallOpFromResultBox(result, fctName, 3);210 else211 checkCallOp(prod.getDefiningOp(), fctName, 2);212}213 214TEST_F(RuntimeCallTest, genDotProduct) {215 testGenDotProduct(*firBuilder, f32Ty, "_FortranADotProductReal4");216 testGenDotProduct(*firBuilder, f64Ty, "_FortranADotProductReal8");217 testGenDotProduct(*firBuilder, f80Ty, "_FortranADotProductReal10");218 testGenDotProduct(*firBuilder, f128Ty, "_FortranADotProductReal16");219 testGenDotProduct(*firBuilder, i8Ty, "_FortranADotProductInteger1");220 testGenDotProduct(*firBuilder, i16Ty, "_FortranADotProductInteger2");221 testGenDotProduct(*firBuilder, i32Ty, "_FortranADotProductInteger4");222 testGenDotProduct(*firBuilder, i64Ty, "_FortranADotProductInteger8");223 testGenDotProduct(*firBuilder, i128Ty, "_FortranADotProductInteger16");224 testGenDotProduct(*firBuilder, c4Ty, "_FortranACppDotProductComplex4");225 testGenDotProduct(*firBuilder, c8Ty, "_FortranACppDotProductComplex8");226 testGenDotProduct(*firBuilder, c10Ty, "_FortranACppDotProductComplex10");227 testGenDotProduct(*firBuilder, c16Ty, "_FortranACppDotProductComplex16");228}229 230void checkGenMxxloc(fir::FirOpBuilder &builder, mlir::Type eleTy,231 void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,232 mlir::Value, mlir::Value, mlir::Value, mlir::Value),233 llvm::StringRef fctName, unsigned nbArgs) {234 mlir::Location loc = builder.getUnknownLoc();235 mlir::Type i32Ty = builder.getI32Type();236 mlir::Type seqTy =237 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), eleTy);238 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);239 mlir::Value a = fir::UndefOp::create(builder, loc, refSeqTy);240 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);241 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);242 mlir::Value kind = builder.createIntegerConstant(loc, i32Ty, 1);243 mlir::Value back = builder.createIntegerConstant(loc, i32Ty, 1);244 genFct(builder, loc, result, a, mask, kind, back);245 checkCallOpFromResultBox(result, fctName, nbArgs);246}247 248TEST_F(RuntimeCallTest, genMaxlocTest) {249 checkGenMxxloc(*firBuilder, char1Ty, fir::runtime::genMaxloc,250 "_FortranAMaxlocCharacter", 5);251 checkGenMxxloc(*firBuilder, char2Ty, fir::runtime::genMaxloc,252 "_FortranAMaxlocCharacter", 5);253 checkGenMxxloc(*firBuilder, char4Ty, fir::runtime::genMaxloc,254 "_FortranAMaxlocCharacter", 5);255 checkGenMxxloc(256 *firBuilder, i8Ty, fir::runtime::genMaxloc, "_FortranAMaxlocInteger1", 5);257 checkGenMxxloc(*firBuilder, i16Ty, fir::runtime::genMaxloc,258 "_FortranAMaxlocInteger2", 5);259 checkGenMxxloc(*firBuilder, i32Ty, fir::runtime::genMaxloc,260 "_FortranAMaxlocInteger4", 5);261 checkGenMxxloc(*firBuilder, i64Ty, fir::runtime::genMaxloc,262 "_FortranAMaxlocInteger8", 5);263 checkGenMxxloc(*firBuilder, i128Ty, fir::runtime::genMaxloc,264 "_FortranAMaxlocInteger16", 5);265 checkGenMxxloc(266 *firBuilder, f32Ty, fir::runtime::genMaxloc, "_FortranAMaxlocReal4", 5);267 checkGenMxxloc(268 *firBuilder, f64Ty, fir::runtime::genMaxloc, "_FortranAMaxlocReal8", 5);269 checkGenMxxloc(270 *firBuilder, f80Ty, fir::runtime::genMaxloc, "_FortranAMaxlocReal10", 5);271 checkGenMxxloc(272 *firBuilder, f128Ty, fir::runtime::genMaxloc, "_FortranAMaxlocReal16", 5);273}274 275TEST_F(RuntimeCallTest, genMinlocTest) {276 checkGenMxxloc(*firBuilder, char1Ty, fir::runtime::genMinloc,277 "_FortranAMinlocCharacter", 5);278 checkGenMxxloc(*firBuilder, char2Ty, fir::runtime::genMinloc,279 "_FortranAMinlocCharacter", 5);280 checkGenMxxloc(*firBuilder, char4Ty, fir::runtime::genMinloc,281 "_FortranAMinlocCharacter", 5);282 checkGenMxxloc(283 *firBuilder, i8Ty, fir::runtime::genMinloc, "_FortranAMinlocInteger1", 5);284 checkGenMxxloc(*firBuilder, i16Ty, fir::runtime::genMinloc,285 "_FortranAMinlocInteger2", 5);286 checkGenMxxloc(*firBuilder, i32Ty, fir::runtime::genMinloc,287 "_FortranAMinlocInteger4", 5);288 checkGenMxxloc(*firBuilder, i64Ty, fir::runtime::genMinloc,289 "_FortranAMinlocInteger8", 5);290 checkGenMxxloc(*firBuilder, i128Ty, fir::runtime::genMinloc,291 "_FortranAMinlocInteger16", 5);292 checkGenMxxloc(293 *firBuilder, f32Ty, fir::runtime::genMinloc, "_FortranAMinlocReal4", 5);294 checkGenMxxloc(295 *firBuilder, f64Ty, fir::runtime::genMinloc, "_FortranAMinlocReal8", 5);296 checkGenMxxloc(297 *firBuilder, f80Ty, fir::runtime::genMinloc, "_FortranAMinlocReal10", 5);298 checkGenMxxloc(299 *firBuilder, f128Ty, fir::runtime::genMinloc, "_FortranAMinlocReal16", 5);300}301 302void checkGenMxxlocDim(fir::FirOpBuilder &builder,303 void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,304 mlir::Value, mlir::Value, mlir::Value, mlir::Value, mlir::Value),305 llvm::StringRef fctName, unsigned nbArgs) {306 mlir::Location loc = builder.getUnknownLoc();307 auto i32Ty = builder.getI32Type();308 mlir::Type seqTy =309 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);310 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);311 mlir::Value a = fir::UndefOp::create(builder, loc, refSeqTy);312 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);313 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);314 mlir::Value kind = builder.createIntegerConstant(loc, i32Ty, 1);315 mlir::Value dim = builder.createIntegerConstant(loc, i32Ty, 1);316 mlir::Value back = builder.createIntegerConstant(loc, i32Ty, 1);317 genFct(builder, loc, result, a, dim, mask, kind, back);318 checkCallOpFromResultBox(result, fctName, nbArgs);319}320 321TEST_F(RuntimeCallTest, genMaxlocDimTest) {322 checkGenMxxlocDim(323 *firBuilder, fir::runtime::genMaxlocDim, "_FortranAMaxlocDim", 6);324}325 326TEST_F(RuntimeCallTest, genMinlocDimTest) {327 checkGenMxxlocDim(328 *firBuilder, fir::runtime::genMinlocDim, "_FortranAMinlocDim", 6);329}330 331void checkGenMxxvalChar(fir::FirOpBuilder &builder,332 void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,333 mlir::Value, mlir::Value),334 llvm::StringRef fctName, unsigned nbArgs) {335 mlir::Location loc = builder.getUnknownLoc();336 auto i32Ty = builder.getI32Type();337 mlir::Type seqTy =338 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);339 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);340 mlir::Value a = fir::UndefOp::create(builder, loc, refSeqTy);341 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);342 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);343 genFct(builder, loc, result, a, mask);344 checkCallOpFromResultBox(result, fctName, nbArgs);345}346 347TEST_F(RuntimeCallTest, genMaxvalCharTest) {348 checkGenMxxvalChar(349 *firBuilder, fir::runtime::genMaxvalChar, "_FortranAMaxvalCharacter", 3);350}351 352TEST_F(RuntimeCallTest, genMinvalCharTest) {353 checkGenMxxvalChar(354 *firBuilder, fir::runtime::genMinvalChar, "_FortranAMinvalCharacter", 3);355}356 357void checkGen4argsDim(fir::FirOpBuilder &builder,358 void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,359 mlir::Value, mlir::Value, mlir::Value),360 llvm::StringRef fctName, unsigned nbArgs) {361 mlir::Location loc = builder.getUnknownLoc();362 auto i32Ty = builder.getI32Type();363 mlir::Type seqTy =364 fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);365 mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);366 mlir::Value a = fir::UndefOp::create(builder, loc, refSeqTy);367 mlir::Value result = fir::UndefOp::create(builder, loc, seqTy);368 mlir::Value mask = fir::UndefOp::create(builder, loc, seqTy);369 mlir::Value dim = builder.createIntegerConstant(loc, i32Ty, 1);370 genFct(builder, loc, result, a, dim, mask);371 checkCallOpFromResultBox(result, fctName, nbArgs);372}373 374TEST_F(RuntimeCallTest, genMaxvalDimTest) {375 checkGen4argsDim(376 *firBuilder, fir::runtime::genMaxvalDim, "_FortranAMaxvalDim", 4);377}378 379TEST_F(RuntimeCallTest, genMinvalDimTest) {380 checkGen4argsDim(381 *firBuilder, fir::runtime::genMinvalDim, "_FortranAMinvalDim", 4);382}383 384TEST_F(RuntimeCallTest, genProductDimTest) {385 checkGen4argsDim(386 *firBuilder, fir::runtime::genProductDim, "_FortranAProductDim", 4);387}388 389TEST_F(RuntimeCallTest, genSumDimTest) {390 checkGen4argsDim(*firBuilder, fir::runtime::genSumDim, "_FortranASumDim", 4);391}392