1 //===- CharacterTest.cpp -- Character 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/Character.h" 10 #include "RuntimeCallTestBase.h" 11 #include "gtest/gtest.h" 12 #include "flang/Optimizer/Builder/Character.h" 13 14 using namespace mlir; 15 16 TEST_F(RuntimeCallTest, genAdjustLTest) { 17 auto loc = firBuilder->getUnknownLoc(); 18 mlir::Value result = firBuilder->create<fir::UndefOp>(loc, boxTy); 19 mlir::Value string = firBuilder->create<fir::UndefOp>(loc, boxTy); 20 fir::runtime::genAdjustL(*firBuilder, loc, result, string); 21 checkCallOpFromResultBox(result, "_FortranAAdjustl", 2); 22 } 23 24 TEST_F(RuntimeCallTest, genAdjustRTest) { 25 auto loc = firBuilder->getUnknownLoc(); 26 mlir::Value result = firBuilder->create<fir::UndefOp>(loc, boxTy); 27 mlir::Value string = firBuilder->create<fir::UndefOp>(loc, boxTy); 28 fir::runtime::genAdjustR(*firBuilder, loc, result, string); 29 checkCallOpFromResultBox(result, "_FortranAAdjustr", 2); 30 } 31 32 void checkCharCompare1( 33 fir::FirOpBuilder &builder, mlir::Type type, llvm::StringRef fctName) { 34 auto loc = builder.getUnknownLoc(); 35 mlir::Type i32Ty = IntegerType::get(builder.getContext(), 32); 36 mlir::Value lhsBuff = builder.create<fir::UndefOp>(loc, type); 37 mlir::Value lhsLen = builder.create<fir::UndefOp>(loc, i32Ty); 38 mlir::Value rhsBuff = builder.create<fir::UndefOp>(loc, type); 39 mlir::Value rhsLen = builder.create<fir::UndefOp>(loc, i32Ty); 40 mlir::Value res = fir::runtime::genCharCompare(builder, loc, 41 mlir::arith::CmpIPredicate::eq, lhsBuff, lhsLen, rhsBuff, rhsLen); 42 checkCallOpFromResultBox(lhsBuff, fctName, 4, /*addLocArgs=*/false); 43 EXPECT_TRUE(mlir::isa<mlir::arith::CmpIOp>(res.getDefiningOp())); 44 } 45 46 void checkCharCompare1AllTypeForKind( 47 fir::FirOpBuilder &builder, llvm::StringRef fctName, unsigned kind) { 48 mlir::Type charTy = fir::CharacterType::get(builder.getContext(), kind, 10); 49 mlir::Type seqCharTy = fir::SequenceType::get(charTy, 10); 50 mlir::Type refCharTy = fir::ReferenceType::get(charTy); 51 mlir::Type boxCharTy = fir::BoxCharType::get(builder.getContext(), kind); 52 mlir::Type boxTy = fir::BoxType::get(charTy); 53 checkCharCompare1(builder, charTy, fctName); 54 checkCharCompare1(builder, seqCharTy, fctName); 55 checkCharCompare1(builder, refCharTy, fctName); 56 checkCharCompare1(builder, boxCharTy, fctName); 57 checkCharCompare1(builder, boxTy, fctName); 58 } 59 60 TEST_F(RuntimeCallTest, genCharCompar1Test) { 61 checkCharCompare1AllTypeForKind( 62 *firBuilder, "_FortranACharacterCompareScalar1", 1); 63 checkCharCompare1AllTypeForKind( 64 *firBuilder, "_FortranACharacterCompareScalar2", 2); 65 checkCharCompare1AllTypeForKind( 66 *firBuilder, "_FortranACharacterCompareScalar4", 4); 67 } 68 69 void checkCharCompare2( 70 fir::FirOpBuilder &builder, llvm::StringRef fctName, unsigned kind) { 71 auto loc = builder.getUnknownLoc(); 72 fir::factory::CharacterExprHelper charHelper(builder, loc); 73 mlir::Type i32Ty = IntegerType::get(builder.getContext(), 32); 74 mlir::Type boxCharTy = fir::BoxCharType::get(builder.getContext(), kind); 75 mlir::Value lhsBuff = builder.create<fir::UndefOp>(loc, boxCharTy); 76 mlir::Value lhsLen = builder.create<fir::UndefOp>(loc, i32Ty); 77 mlir::Value rhsBuff = builder.create<fir::UndefOp>(loc, boxCharTy); 78 mlir::Value rhsLen = builder.create<fir::UndefOp>(loc, i32Ty); 79 fir::ExtendedValue lhs = charHelper.toExtendedValue(lhsBuff, lhsLen); 80 fir::ExtendedValue rhs = charHelper.toExtendedValue(rhsBuff, rhsLen); 81 mlir::Value res = fir::runtime::genCharCompare( 82 builder, loc, mlir::arith::CmpIPredicate::eq, lhs, rhs); 83 EXPECT_TRUE(mlir::isa<mlir::arith::CmpIOp>(res.getDefiningOp())); 84 auto cmpOp = mlir::dyn_cast<mlir::arith::CmpIOp>(res.getDefiningOp()); 85 checkCallOp(cmpOp.getLhs().getDefiningOp(), fctName, 4, /*addLocArgs=*/false); 86 auto allocas = res.getParentBlock()->getOps<fir::AllocaOp>(); 87 EXPECT_TRUE(llvm::empty(allocas)); 88 } 89 90 TEST_F(RuntimeCallTest, genCharCompare2Test) { 91 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar1", 1); 92 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar2", 2); 93 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar4", 4); 94 } 95 96 void checkGenIndex( 97 fir::FirOpBuilder &builder, llvm::StringRef fctName, unsigned kind) { 98 auto loc = builder.getUnknownLoc(); 99 mlir::Type i32Ty = IntegerType::get(builder.getContext(), 32); 100 mlir::Value stringBase = builder.create<fir::UndefOp>(loc, i32Ty); 101 mlir::Value stringLen = builder.create<fir::UndefOp>(loc, i32Ty); 102 mlir::Value substringBase = builder.create<fir::UndefOp>(loc, i32Ty); 103 mlir::Value substringLen = builder.create<fir::UndefOp>(loc, i32Ty); 104 mlir::Value back = builder.create<fir::UndefOp>(loc, i32Ty); 105 mlir::Value res = fir::runtime::genIndex(builder, loc, kind, stringBase, 106 stringLen, substringBase, substringLen, back); 107 checkCallOp(res.getDefiningOp(), fctName, 5, /*addLocArgs=*/false); 108 } 109 110 TEST_F(RuntimeCallTest, genIndexTest) { 111 checkGenIndex(*firBuilder, "_FortranAIndex1", 1); 112 checkGenIndex(*firBuilder, "_FortranAIndex2", 2); 113 checkGenIndex(*firBuilder, "_FortranAIndex4", 4); 114 } 115 116 TEST_F(RuntimeCallTest, genIndexDescriptorTest) { 117 auto loc = firBuilder->getUnknownLoc(); 118 mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 119 mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 120 mlir::Value substringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 121 mlir::Value backOpt = firBuilder->create<fir::UndefOp>(loc, boxTy); 122 mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty); 123 fir::runtime::genIndexDescriptor( 124 *firBuilder, loc, resultBox, stringBox, substringBox, backOpt, kind); 125 checkCallOpFromResultBox(resultBox, "_FortranAIndex", 5); 126 } 127 128 TEST_F(RuntimeCallTest, genRepeatTest) { 129 auto loc = firBuilder->getUnknownLoc(); 130 mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 131 mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 132 mlir::Value ncopies = firBuilder->create<fir::UndefOp>(loc, i32Ty); 133 fir::runtime::genRepeat(*firBuilder, loc, resultBox, stringBox, ncopies); 134 checkCallOpFromResultBox(resultBox, "_FortranARepeat", 3); 135 } 136 137 TEST_F(RuntimeCallTest, genTrimTest) { 138 auto loc = firBuilder->getUnknownLoc(); 139 mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 140 mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 141 fir::runtime::genTrim(*firBuilder, loc, resultBox, stringBox); 142 checkCallOpFromResultBox(resultBox, "_FortranATrim", 2); 143 } 144 145 TEST_F(RuntimeCallTest, genScanDescriptorTest) { 146 auto loc = firBuilder->getUnknownLoc(); 147 mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 148 mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 149 mlir::Value setBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 150 mlir::Value backBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 151 mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty); 152 fir::runtime::genScanDescriptor( 153 *firBuilder, loc, resultBox, stringBox, setBox, backBox, kind); 154 checkCallOpFromResultBox(resultBox, "_FortranAScan", 5); 155 } 156 157 void checkGenScan( 158 fir::FirOpBuilder &builder, llvm::StringRef fctName, unsigned kind) { 159 auto loc = builder.getUnknownLoc(); 160 mlir::Type charTy = fir::CharacterType::get(builder.getContext(), kind, 10); 161 mlir::Type boxTy = fir::BoxType::get(charTy); 162 mlir::Type i32Ty = IntegerType::get(builder.getContext(), 32); 163 mlir::Value stringBase = builder.create<fir::UndefOp>(loc, boxTy); 164 mlir::Value stringLen = builder.create<fir::UndefOp>(loc, i32Ty); 165 mlir::Value setBase = builder.create<fir::UndefOp>(loc, boxTy); 166 mlir::Value setLen = builder.create<fir::UndefOp>(loc, i32Ty); 167 mlir::Value back = builder.create<fir::UndefOp>(loc, i32Ty); 168 mlir::Value res = fir::runtime::genScan( 169 builder, loc, kind, stringBase, stringLen, setBase, setLen, back); 170 checkCallOp(res.getDefiningOp(), fctName, 5, /*addLocArgs=*/false); 171 } 172 173 TEST_F(RuntimeCallTest, genScanTest) { 174 checkGenScan(*firBuilder, "_FortranAScan1", 1); 175 checkGenScan(*firBuilder, "_FortranAScan2", 2); 176 checkGenScan(*firBuilder, "_FortranAScan4", 4); 177 } 178 179 TEST_F(RuntimeCallTest, genVerifyDescriptorTest) { 180 auto loc = firBuilder->getUnknownLoc(); 181 mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 182 mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 183 mlir::Value setBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 184 mlir::Value backBox = firBuilder->create<fir::UndefOp>(loc, boxTy); 185 mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty); 186 fir::runtime::genVerifyDescriptor( 187 *firBuilder, loc, resultBox, stringBox, setBox, backBox, kind); 188 checkCallOpFromResultBox(resultBox, "_FortranAVerify", 5); 189 } 190 191 void checkGenVerify( 192 fir::FirOpBuilder &builder, llvm::StringRef fctName, unsigned kind) { 193 auto loc = builder.getUnknownLoc(); 194 mlir::Type charTy = fir::CharacterType::get(builder.getContext(), kind, 10); 195 mlir::Type boxTy = fir::BoxType::get(charTy); 196 mlir::Type i32Ty = IntegerType::get(builder.getContext(), 32); 197 mlir::Value stringBase = builder.create<fir::UndefOp>(loc, boxTy); 198 mlir::Value stringLen = builder.create<fir::UndefOp>(loc, i32Ty); 199 mlir::Value setBase = builder.create<fir::UndefOp>(loc, boxTy); 200 mlir::Value setLen = builder.create<fir::UndefOp>(loc, i32Ty); 201 mlir::Value back = builder.create<fir::UndefOp>(loc, i32Ty); 202 mlir::Value res = fir::runtime::genVerify( 203 builder, loc, kind, stringBase, stringLen, setBase, setLen, back); 204 checkCallOp(res.getDefiningOp(), fctName, 5, /*addLocArgs=*/false); 205 } 206 207 TEST_F(RuntimeCallTest, genVerifyTest) { 208 checkGenVerify(*firBuilder, "_FortranAVerify1", 1); 209 checkGenVerify(*firBuilder, "_FortranAVerify2", 2); 210 checkGenVerify(*firBuilder, "_FortranAVerify4", 4); 211 } 212