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(AArch64GISelMITest, 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(AArch64GISelMITest, 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 // Match shl, and make sure a different shift amount type works. 142 auto Shl = B.buildShl(s64, Copies[0], TruncCopy1); 143 match = mi_match(Shl.getReg(0), *MRI, 144 m_GShl(m_Reg(Src0), m_Reg(Src1))); 145 EXPECT_TRUE(match); 146 EXPECT_EQ(Src0, Copies[0]); 147 EXPECT_EQ(Src1, TruncCopy1.getReg(0)); 148 } 149 150 TEST_F(AArch64GISelMITest, MatchICmp) { 151 setUp(); 152 if (!TM) 153 return; 154 155 const LLT s1 = LLT::scalar(1); 156 auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]); 157 158 // Check match any predicate. 159 bool match = 160 mi_match(CmpEq.getReg(0), *MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg())); 161 EXPECT_TRUE(match); 162 163 // Check we get the predicate and registers. 164 CmpInst::Predicate Pred; 165 Register Reg0; 166 Register Reg1; 167 match = mi_match(CmpEq.getReg(0), *MRI, 168 m_GICmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1))); 169 EXPECT_TRUE(match); 170 EXPECT_EQ(CmpInst::ICMP_EQ, Pred); 171 EXPECT_EQ(Copies[0], Reg0); 172 EXPECT_EQ(Copies[1], Reg1); 173 } 174 175 TEST_F(AArch64GISelMITest, MatchFCmp) { 176 setUp(); 177 if (!TM) 178 return; 179 180 const LLT s1 = LLT::scalar(1); 181 auto CmpEq = B.buildFCmp(CmpInst::FCMP_OEQ, s1, Copies[0], Copies[1]); 182 183 // Check match any predicate. 184 bool match = 185 mi_match(CmpEq.getReg(0), *MRI, m_GFCmp(m_Pred(), m_Reg(), m_Reg())); 186 EXPECT_TRUE(match); 187 188 // Check we get the predicate and registers. 189 CmpInst::Predicate Pred; 190 Register Reg0; 191 Register Reg1; 192 match = mi_match(CmpEq.getReg(0), *MRI, 193 m_GFCmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1))); 194 EXPECT_TRUE(match); 195 EXPECT_EQ(CmpInst::FCMP_OEQ, Pred); 196 EXPECT_EQ(Copies[0], Reg0); 197 EXPECT_EQ(Copies[1], Reg1); 198 } 199 200 TEST_F(AArch64GISelMITest, MatchFPUnaryOp) { 201 setUp(); 202 if (!TM) 203 return; 204 205 // Truncate s64 to s32. 206 LLT s32 = LLT::scalar(32); 207 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]); 208 209 // Match G_FABS. 210 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32}); 211 bool match = 212 mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg())); 213 EXPECT_TRUE(match); 214 215 Register Src; 216 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32}); 217 match = mi_match(MIBFNeg.getReg(0), *MRI, m_GFNeg(m_Reg(Src))); 218 EXPECT_TRUE(match); 219 EXPECT_EQ(Src, Copy0s32.getReg(0)); 220 221 match = mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg(Src))); 222 EXPECT_TRUE(match); 223 EXPECT_EQ(Src, Copy0s32.getReg(0)); 224 225 // Build and match FConstant. 226 auto MIBFCst = B.buildFConstant(s32, .5); 227 const ConstantFP *TmpFP{}; 228 match = mi_match(MIBFCst.getReg(0), *MRI, m_GFCst(TmpFP)); 229 EXPECT_TRUE(match); 230 EXPECT_TRUE(TmpFP); 231 APFloat APF((float).5); 232 auto *CFP = ConstantFP::get(Context, APF); 233 EXPECT_EQ(CFP, TmpFP); 234 235 // Build double float. 236 LLT s64 = LLT::scalar(64); 237 auto MIBFCst64 = B.buildFConstant(s64, .5); 238 const ConstantFP *TmpFP64{}; 239 match = mi_match(MIBFCst64.getReg(0), *MRI, m_GFCst(TmpFP64)); 240 EXPECT_TRUE(match); 241 EXPECT_TRUE(TmpFP64); 242 APFloat APF64(.5); 243 auto CFP64 = ConstantFP::get(Context, APF64); 244 EXPECT_EQ(CFP64, TmpFP64); 245 EXPECT_NE(TmpFP64, TmpFP); 246 247 // Build half float. 248 LLT s16 = LLT::scalar(16); 249 auto MIBFCst16 = B.buildFConstant(s16, .5); 250 const ConstantFP *TmpFP16{}; 251 match = mi_match(MIBFCst16.getReg(0), *MRI, m_GFCst(TmpFP16)); 252 EXPECT_TRUE(match); 253 EXPECT_TRUE(TmpFP16); 254 bool Ignored; 255 APFloat APF16(.5); 256 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); 257 auto CFP16 = ConstantFP::get(Context, APF16); 258 EXPECT_EQ(TmpFP16, CFP16); 259 EXPECT_NE(TmpFP16, TmpFP); 260 } 261 262 TEST_F(AArch64GISelMITest, MatchExtendsTrunc) { 263 setUp(); 264 if (!TM) 265 return; 266 267 LLT s64 = LLT::scalar(64); 268 LLT s32 = LLT::scalar(32); 269 270 auto MIBTrunc = B.buildTrunc(s32, Copies[0]); 271 auto MIBAExt = B.buildAnyExt(s64, MIBTrunc); 272 auto MIBZExt = B.buildZExt(s64, MIBTrunc); 273 auto MIBSExt = B.buildSExt(s64, MIBTrunc); 274 Register Src0; 275 bool match = 276 mi_match(MIBTrunc.getReg(0), *MRI, m_GTrunc(m_Reg(Src0))); 277 EXPECT_TRUE(match); 278 EXPECT_EQ(Src0, Copies[0]); 279 match = 280 mi_match(MIBAExt.getReg(0), *MRI, m_GAnyExt(m_Reg(Src0))); 281 EXPECT_TRUE(match); 282 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 283 284 match = mi_match(MIBSExt.getReg(0), *MRI, m_GSExt(m_Reg(Src0))); 285 EXPECT_TRUE(match); 286 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 287 288 match = mi_match(MIBZExt.getReg(0), *MRI, m_GZExt(m_Reg(Src0))); 289 EXPECT_TRUE(match); 290 EXPECT_EQ(Src0, MIBTrunc.getReg(0)); 291 292 // Match ext(trunc src) 293 match = mi_match(MIBAExt.getReg(0), *MRI, 294 m_GAnyExt(m_GTrunc(m_Reg(Src0)))); 295 EXPECT_TRUE(match); 296 EXPECT_EQ(Src0, Copies[0]); 297 298 match = mi_match(MIBSExt.getReg(0), *MRI, 299 m_GSExt(m_GTrunc(m_Reg(Src0)))); 300 EXPECT_TRUE(match); 301 EXPECT_EQ(Src0, Copies[0]); 302 303 match = mi_match(MIBZExt.getReg(0), *MRI, 304 m_GZExt(m_GTrunc(m_Reg(Src0)))); 305 EXPECT_TRUE(match); 306 EXPECT_EQ(Src0, Copies[0]); 307 } 308 309 TEST_F(AArch64GISelMITest, MatchSpecificType) { 310 setUp(); 311 if (!TM) 312 return; 313 314 // Try to match a 64bit add. 315 LLT s64 = LLT::scalar(64); 316 LLT s32 = LLT::scalar(32); 317 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 318 EXPECT_FALSE(mi_match(MIBAdd.getReg(0), *MRI, 319 m_GAdd(m_SpecificType(s32), m_Reg()))); 320 EXPECT_TRUE(mi_match(MIBAdd.getReg(0), *MRI, 321 m_GAdd(m_SpecificType(s64), m_Reg()))); 322 323 // Try to match the destination type of a bitcast. 324 LLT v2s32 = LLT::vector(2, 32); 325 auto MIBCast = B.buildCast(v2s32, Copies[0]); 326 EXPECT_TRUE( 327 mi_match(MIBCast.getReg(0), *MRI, m_GBitcast(m_Reg()))); 328 EXPECT_TRUE( 329 mi_match(MIBCast.getReg(0), *MRI, m_SpecificType(v2s32))); 330 EXPECT_TRUE( 331 mi_match(MIBCast.getReg(1), *MRI, m_SpecificType(s64))); 332 333 // Build a PTRToInt and INTTOPTR and match and test them. 334 LLT PtrTy = LLT::pointer(0, 64); 335 auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]); 336 auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr); 337 Register Src0; 338 339 // match the ptrtoint(inttoptr reg) 340 bool match = mi_match(MIBPtrToInt.getReg(0), *MRI, 341 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0)))); 342 EXPECT_TRUE(match); 343 EXPECT_EQ(Src0, Copies[0]); 344 } 345 346 TEST_F(AArch64GISelMITest, MatchCombinators) { 347 setUp(); 348 if (!TM) 349 return; 350 351 LLT s64 = LLT::scalar(64); 352 LLT s32 = LLT::scalar(32); 353 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 354 Register Src0, Src1; 355 bool match = 356 mi_match(MIBAdd.getReg(0), *MRI, 357 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 358 EXPECT_TRUE(match); 359 EXPECT_EQ(Src0, Copies[0]); 360 EXPECT_EQ(Src1, Copies[1]); 361 // Check for s32 (which should fail). 362 match = 363 mi_match(MIBAdd.getReg(0), *MRI, 364 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 365 EXPECT_FALSE(match); 366 match = 367 mi_match(MIBAdd.getReg(0), *MRI, 368 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1)))); 369 EXPECT_TRUE(match); 370 EXPECT_EQ(Src0, Copies[0]); 371 EXPECT_EQ(Src1, Copies[1]); 372 373 // Match a case where none of the predicates hold true. 374 match = mi_match( 375 MIBAdd.getReg(0), *MRI, 376 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg()))); 377 EXPECT_FALSE(match); 378 } 379 380 TEST_F(AArch64GISelMITest, MatchMiscellaneous) { 381 setUp(); 382 if (!TM) 383 return; 384 385 LLT s64 = LLT::scalar(64); 386 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); 387 // Make multiple uses of this add. 388 B.buildCast(LLT::pointer(0, 32), MIBAdd); 389 B.buildCast(LLT::pointer(1, 32), MIBAdd); 390 bool match = mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg())); 391 EXPECT_TRUE(match); 392 match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))); 393 EXPECT_FALSE(match); 394 } 395 } // namespace 396 397 int main(int argc, char **argv) { 398 ::testing::InitGoogleTest(&argc, argv); 399 initLLVM(); 400 return RUN_ALL_TESTS(); 401 } 402