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
14using namespace mlir;
15
16TEST_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
24TEST_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
32void 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
46void 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
60TEST_F(RuntimeCallTest, genCharCompar1Test) {
61 checkCharCompare1AllTypeForKind(
62 *firBuilder, "_FortranACharacterCompareScalar1", 1);
63 checkCharCompare1AllTypeForKind(
64 *firBuilder, "_FortranACharacterCompareScalar2", 2);
65 checkCharCompare1AllTypeForKind(
66 *firBuilder, "_FortranACharacterCompareScalar4", 4);
67}
68
69void 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
90TEST_F(RuntimeCallTest, genCharCompare2Test) {
91 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar1", 1);
92 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar2", 2);
93 checkCharCompare2(*firBuilder, "_FortranACharacterCompareScalar4", 4);
94}
95
96void 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
110TEST_F(RuntimeCallTest, genIndexTest) {
111 checkGenIndex(*firBuilder, "_FortranAIndex1", 1);
112 checkGenIndex(*firBuilder, "_FortranAIndex2", 2);
113 checkGenIndex(*firBuilder, "_FortranAIndex4", 4);
114}
115
116TEST_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
128TEST_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
137TEST_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
145TEST_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
157void 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
173TEST_F(RuntimeCallTest, genScanTest) {
174 checkGenScan(*firBuilder, "_FortranAScan1", 1);
175 checkGenScan(*firBuilder, "_FortranAScan2", 2);
176 checkGenScan(*firBuilder, "_FortranAScan4", 4);
177}
178
179TEST_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
191void 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
207TEST_F(RuntimeCallTest, genVerifyTest) {
208 checkGenVerify(*firBuilder, "_FortranAVerify1", 1);
209 checkGenVerify(*firBuilder, "_FortranAVerify2", 2);
210 checkGenVerify(*firBuilder, "_FortranAVerify4", 4);
211}
212

source code of flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp