1 //===- PatternMatchTest.cpp -----------------------------------------------===// 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 "GISelMITest.h" 10 #include "llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h" 11 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 13 #include "llvm/CodeGen/GlobalISel/Utils.h" 14 #include "llvm/CodeGen/MIRParser/MIRParser.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineModuleInfo.h" 17 #include "llvm/CodeGen/TargetFrameLowering.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 #include "llvm/CodeGen/TargetLowering.h" 20 #include "llvm/CodeGen/TargetSubtargetInfo.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "llvm/Support/TargetRegistry.h" 23 #include "llvm/Support/TargetSelect.h" 24 #include "llvm/Target/TargetMachine.h" 25 #include "llvm/Target/TargetOptions.h" 26 #include "gtest/gtest.h" 27 28 using namespace llvm; 29 using namespace MIPatternMatch; 30 31 namespace { 32 33 TEST_F(GISelMITest, MatchIntConstant) { 34 setUp(); 35 if (!TM) 36 return; 37 auto MIBCst = B.buildConstant(LLT::scalar(64), 42); 38 int64_t Cst; 39 bool match = mi_match(MIBCst.getReg(0), *MRI, m_ICst(Cst)); 40 EXPECT_TRUE(match); 41 EXPECT_EQ(Cst, 42); 42 } 43 44 TEST_F(GISelMITest, MatchBinaryOp) { 45 setUp(); 46 if (!TM) 47 return; 48 LLT s32 = LLT::scalar(32); 49 LLT s64 = LLT::scalar(64); 50 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 51 // Test case for no bind. 52 bool match = 53 mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg())); 54 EXPECT_TRUE(match); 55 Register Src0, Src1, Src2; 56 match = mi_match(MIBAdd.getReg(0), *MRI, 57 m_GAdd(m_Reg(Src0), m_Reg(Src1))); 58 EXPECT_TRUE(match); 59 EXPECT_EQ(Src0, Copies[0]); 60 EXPECT_EQ(Src1, Copies[1]); 61 62 // Build MUL(ADD %0, %1), %2 63 auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]); 64 65 // Try to match MUL. 66 match = mi_match(MIBMul.getReg(0), *MRI, 67 m_GMul(m_Reg(Src0), m_Reg(Src1))); 68 EXPECT_TRUE(match); 69 EXPECT_EQ(Src0, MIBAdd.getReg(0)); 70 EXPECT_EQ(Src1, Copies[2]); 71 72 // Try to match MUL(ADD) 73 match = mi_match(MIBMul.getReg(0), *MRI, 74 m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2))); 75 EXPECT_TRUE(match); 76 EXPECT_EQ(Src0, Copies[0]); 77 EXPECT_EQ(Src1, Copies[1]); 78 EXPECT_EQ(Src2, Copies[2]); 79 80 // Test Commutativity. 81 auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42)); 82 // Try to match MUL(Cst, Reg) on src of MUL(Reg, Cst) to validate 83 // commutativity. 84 int64_t Cst; 85 match = mi_match(MIBMul2.getReg(0), *MRI, 86 m_GMul(m_ICst(Cst), m_Reg(Src0))); 87 EXPECT_TRUE(match); 88 EXPECT_EQ(Cst, 42); 89 EXPECT_EQ(Src0, Copies[0]); 90 91 // Make sure commutative doesn't work with something like SUB. 92 auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42)); 93 match = mi_match(MIBSub.getReg(0), *MRI, 94 m_GSub(m_ICst(Cst), m_Reg(Src0))); 95 EXPECT_FALSE(match); 96 97 auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, {s64}, 98 {Copies[0], B.buildConstant(s64, 42)}); 99 // Match and test commutativity for FMUL. 100 match = mi_match(MIBFMul.getReg(0), *MRI, 101 m_GFMul(m_ICst(Cst), m_Reg(Src0))); 102 EXPECT_TRUE(match); 103 EXPECT_EQ(Cst, 42); 104 EXPECT_EQ(Src0, Copies[0]); 105 106 // FSUB 107 auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, {s64}, 108 {Copies[0], B.buildConstant(s64, 42)}); 109 match = mi_match(MIBFSub.getReg(0), *MRI, 110 m_GFSub(m_Reg(Src0), m_Reg())); 111 EXPECT_TRUE(match); 112 EXPECT_EQ(Src0, Copies[0]); 113 114 // Build AND %0, %1 115 auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]); 116 // Try to match AND. 117 match = mi_match(MIBAnd.getReg(0), *MRI, 118 m_GAnd(m_Reg(Src0), m_Reg(Src1))); 119 EXPECT_TRUE(match); 120 EXPECT_EQ(Src0, Copies[0]); 121 EXPECT_EQ(Src1, Copies[1]); 122 123 // Build OR %0, %1 124 auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]); 125 // Try to match OR. 126 match = mi_match(MIBOr.getReg(0), *MRI, 127 m_GOr(m_Reg(Src0), m_Reg(Src1))); 128 EXPECT_TRUE(match); 129 EXPECT_EQ(Src0, Copies[0]); 130 EXPECT_EQ(Src1, Copies[1]); 131 132 // Match lshr, and make sure a different shift amount type works. 133 auto TruncCopy1 = B.buildTrunc(s32, Copies[1]); 134 auto LShr = B.buildLShr(s64, Copies[0], TruncCopy1); 135 match = mi_match(LShr.getReg(0), *MRI, 136 m_GLShr(m_Reg(Src0), m_Reg(Src1))); 137 EXPECT_TRUE(match); 138 EXPECT_EQ(Src0, Copies[0]); 139 EXPECT_EQ(Src1, TruncCopy1.getReg(0)); 140 } 141 142 TEST_F(GISelMITest, MatchICmp) { 143 setUp(); 144 if (!TM) 145 return; 146 147 const LLT s1 = LLT::scalar(1); 148 auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]); 149 150 // Check match any predicate. 151 bool match = 152 mi_match(CmpEq.getReg(0), *MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg())); 153 EXPECT_TRUE(match); 154 155 // Check we get the predicate and registers. 156 CmpInst::Predicate Pred; 157 Register Reg0; 158 Register Reg1; 159 match = mi_match(CmpEq.getReg(0), *MRI, 160 m_GICmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1))); 161 EXPECT_TRUE(match); 162 EXPECT_EQ(CmpInst::ICMP_EQ, Pred); 163 EXPECT_EQ(Copies[0], Reg0); 164 EXPECT_EQ(Copies[1], Reg1); 165 } 166 167 TEST_F(GISelMITest, MatchFCmp) { 168 setUp(); 169 if (!TM) 170 return; 171 172 const LLT s1 = LLT::scalar(1); 173 auto CmpEq = B.buildFCmp(CmpInst::FCMP_OEQ, s1, Copies[0], Copies[1]); 174 175 // Check match any predicate. 176 bool match = 177 mi_match(CmpEq.getReg(0), *MRI, m_GFCmp(m_Pred(), m_Reg(), m_Reg())); 178 EXPECT_TRUE(match); 179 180 // Check we get the predicate and registers. 181 CmpInst::Predicate Pred; 182 Register Reg0; 183 Register Reg1; 184 match = mi_match(CmpEq.getReg(0), *MRI, 185 m_GFCmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1))); 186 EXPECT_TRUE(match); 187 EXPECT_EQ(CmpInst::FCMP_OEQ, Pred); 188 EXPECT_EQ(Copies[0], Reg0); 189 EXPECT_EQ(Copies[1], Reg1); 190 } 191 192 TEST_F(GISelMITest, MatchFPUnaryOp) { 193 setUp(); 194 if (!TM) 195 return; 196 197 // Truncate s64 to s32. 198 LLT s32 = LLT::scalar(32); 199 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]); 200 201 // Match G_FABS. 202 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32}); 203 bool match = 204 mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg())); 205 EXPECT_TRUE(match); 206 207 Register Src; 208 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32}); 209 match = mi_match(MIBFNeg.getReg(0), *MRI, m_GFNeg(m_Reg(Src))); 210 EXPECT_TRUE(match); 211 EXPECT_EQ(Src, Copy0s32.getReg(0)); 212 213 match = mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg(Src))); 214 EXPECT_TRUE(match); 215 EXPECT_EQ(Src, Copy0s32.getReg(0)); 216 217 // Build and match FConstant. 218 auto MIBFCst = B.buildFConstant(s32, .5); 219 const ConstantFP *TmpFP{}; 220 match = mi_match(MIBFCst.getReg(0), *MRI, m_GFCst(TmpFP)); 221 EXPECT_TRUE(match); 222 EXPECT_TRUE(TmpFP); 223 APFloat APF((float).5); 224 auto *CFP = ConstantFP::get(Context, APF); 225 EXPECT_EQ(CFP, TmpFP); 226 227 // Build double float. 228 LLT s64 = LLT::scalar(64); 229 auto MIBFCst64 = B.buildFConstant(s64, .5); 230 const ConstantFP *TmpFP64{}; 231 match = mi_match(MIBFCst64.getReg(0), *MRI, m_GFCst(TmpFP64)); 232 EXPECT_TRUE(match); 233 EXPECT_TRUE(TmpFP64); 234 APFloat APF64(.5); 235 auto CFP64 = ConstantFP::get(Context, APF64); 236 EXPECT_EQ(CFP64, TmpFP64); 237 EXPECT_NE(TmpFP64, TmpFP); 238 239 // Build half float. 240 LLT s16 = LLT::scalar(16); 241 auto MIBFCst16 = B.buildFConstant(s16, .5); 242 const ConstantFP *TmpFP16{}; 243 match = mi_match(MIBFCst16.getReg(0), *MRI, m_GFCst(TmpFP16)); 244 EXPECT_TRUE(match); 245 EXPECT_TRUE(TmpFP16); 246 bool Ignored; 247 APFloat APF16(.5); 248 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); 249 auto CFP16 = ConstantFP::get(Context, APF16); 250 EXPECT_EQ(TmpFP16, CFP16); 251 EXPECT_NE(TmpFP16, TmpFP); 252 } 253 254 TEST_F(GISelMITest, MatchExtendsTrunc) { 255 setUp(); 256 if (!TM) 257 return; 258 259 LLT s64 = LLT::scalar(64); 260 LLT s32 = LLT::scalar(32); 261 262 auto MIBTrunc = B.buildTrunc(s32, Copies[0]); 263 auto MIBAExt = B.buildAnyExt(s64, MIBTrunc); 264 auto MIBZExt = B.buildZExt(s64, MIBTrunc); 265 auto MIBSExt = B.buildSExt(s64, MIBTrunc); 266 Register Src0; 267 bool match = 268 mi_match(MIBTrunc.getReg(0), *MRI, m_GTrunc(m_Reg(Src0))); 269 EXPECT_TRUE(match); 270 EXPECT_EQ(Src0, Copies[0]); 271 match = 272 mi_match(MIBAExt.getReg(0), *MRI, m_GAnyExt(m_Reg(Src0))); 273 EXPECT_TRUE(match); 274 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 275 276 match = mi_match(MIBSExt.getReg(0), *MRI, m_GSExt(m_Reg(Src0))); 277 EXPECT_TRUE(match); 278 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 279 280 match = mi_match(MIBZExt.getReg(0), *MRI, m_GZExt(m_Reg(Src0))); 281 EXPECT_TRUE(match); 282 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 283 284 // Match ext(trunc src) 285 match = mi_match(MIBAExt.getReg(0), *MRI, 286 m_GAnyExt(m_GTrunc(m_Reg(Src0)))); 287 EXPECT_TRUE(match); 288 EXPECT_EQ(Src0, Copies[0]); 289 290 match = mi_match(MIBSExt.getReg(0), *MRI, 291 m_GSExt(m_GTrunc(m_Reg(Src0)))); 292 EXPECT_TRUE(match); 293 EXPECT_EQ(Src0, Copies[0]); 294 295 match = mi_match(MIBZExt.getReg(0), *MRI, 296 m_GZExt(m_GTrunc(m_Reg(Src0)))); 297 EXPECT_TRUE(match); 298 EXPECT_EQ(Src0, Copies[0]); 299 } 300 301 TEST_F(GISelMITest, MatchSpecificType) { 302 setUp(); 303 if (!TM) 304 return; 305 306 // Try to match a 64bit add. 307 LLT s64 = LLT::scalar(64); 308 LLT s32 = LLT::scalar(32); 309 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 310 EXPECT_FALSE(mi_match(MIBAdd.getReg(0), *MRI, 311 m_GAdd(m_SpecificType(s32), m_Reg()))); 312 EXPECT_TRUE(mi_match(MIBAdd.getReg(0), *MRI, 313 m_GAdd(m_SpecificType(s64), m_Reg()))); 314 315 // Try to match the destination type of a bitcast. 316 LLT v2s32 = LLT::vector(2, 32); 317 auto MIBCast = B.buildCast(v2s32, Copies[0]); 318 EXPECT_TRUE( 319 mi_match(MIBCast.getReg(0), *MRI, m_GBitcast(m_Reg()))); 320 EXPECT_TRUE( 321 mi_match(MIBCast.getReg(0), *MRI, m_SpecificType(v2s32))); 322 EXPECT_TRUE( 323 mi_match(MIBCast.getReg(1), *MRI, m_SpecificType(s64))); 324 325 // Build a PTRToInt and INTTOPTR and match and test them. 326 LLT PtrTy = LLT::pointer(0, 64); 327 auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]); 328 auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr); 329 Register Src0; 330 331 // match the ptrtoint(inttoptr reg) 332 bool match = mi_match(MIBPtrToInt.getReg(0), *MRI, 333 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0)))); 334 EXPECT_TRUE(match); 335 EXPECT_EQ(Src0, Copies[0]); 336 } 337 338 TEST_F(GISelMITest, MatchCombinators) { 339 setUp(); 340 if (!TM) 341 return; 342 343 LLT s64 = LLT::scalar(64); 344 LLT s32 = LLT::scalar(32); 345 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 346 Register Src0, Src1; 347 bool match = 348 mi_match(MIBAdd.getReg(0), *MRI, 349 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 350 EXPECT_TRUE(match); 351 EXPECT_EQ(Src0, Copies[0]); 352 EXPECT_EQ(Src1, Copies[1]); 353 // Check for s32 (which should fail). 354 match = 355 mi_match(MIBAdd.getReg(0), *MRI, 356 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 357 EXPECT_FALSE(match); 358 match = 359 mi_match(MIBAdd.getReg(0), *MRI, 360 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 361 EXPECT_TRUE(match); 362 EXPECT_EQ(Src0, Copies[0]); 363 EXPECT_EQ(Src1, Copies[1]); 364 365 // Match a case where none of the predicates hold true. 366 match = mi_match( 367 MIBAdd.getReg(0), *MRI, 368 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg()))); 369 EXPECT_FALSE(match); 370 } 371 372 TEST_F(GISelMITest, MatchMiscellaneous) { 373 setUp(); 374 if (!TM) 375 return; 376 377 LLT s64 = LLT::scalar(64); 378 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 379 // Make multiple uses of this add. 380 B.buildCast(LLT::pointer(0, 32), MIBAdd); 381 B.buildCast(LLT::pointer(1, 32), MIBAdd); 382 bool match = mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg())); 383 EXPECT_TRUE(match); 384 match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))); 385 EXPECT_FALSE(match); 386 } 387 } // namespace 388 389 int main(int argc, char **argv) { 390 ::testing::InitGoogleTest(&argc, argv); 391 initLLVM(); 392 return RUN_ALL_TESTS(); 393 } 394