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(allocas.empty()); |
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 | |