1023 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "GISelMITest.h"10#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"11#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"12#include "llvm/CodeGen/GlobalISel/Utils.h"13#include "llvm/CodeGen/MIRParser/MIRParser.h"14#include "llvm/CodeGen/MachineFunction.h"15#include "llvm/CodeGen/MachineModuleInfo.h"16#include "llvm/CodeGen/TargetFrameLowering.h"17#include "llvm/CodeGen/TargetInstrInfo.h"18#include "llvm/CodeGen/TargetLowering.h"19#include "llvm/CodeGen/TargetSubtargetInfo.h"20#include "llvm/MC/TargetRegistry.h"21#include "llvm/Support/SourceMgr.h"22#include "llvm/Support/TargetSelect.h"23#include "llvm/Target/TargetMachine.h"24#include "llvm/Target/TargetOptions.h"25#include "gtest/gtest.h"26 27using namespace llvm;28using namespace MIPatternMatch;29 30namespace {31 32TEST_F(AArch64GISelMITest, MatchIntConstant) {33 setUp();34 if (!TM)35 GTEST_SKIP();36 auto MIBCst = B.buildConstant(LLT::scalar(64), 42);37 int64_t Cst;38 bool match = mi_match(MIBCst.getReg(0), *MRI, m_ICst(Cst));39 EXPECT_TRUE(match);40 EXPECT_EQ(Cst, 42);41}42 43TEST_F(AArch64GISelMITest, MatchIntConstantRegister) {44 setUp();45 if (!TM)46 GTEST_SKIP();47 auto MIBCst = B.buildConstant(LLT::scalar(64), 42);48 std::optional<ValueAndVReg> Src0;49 bool match = mi_match(MIBCst.getReg(0), *MRI, m_GCst(Src0));50 EXPECT_TRUE(match);51 EXPECT_EQ(Src0->VReg, MIBCst.getReg(0));52}53 54TEST_F(AArch64GISelMITest, MatchIntConstantSplat) {55 setUp();56 if (!TM)57 GTEST_SKIP();58 59 LLT s64 = LLT::scalar(64);60 LLT v2s64 = LLT::fixed_vector(2, s64);61 LLT v4s64 = LLT::fixed_vector(4, s64);62 63 MachineInstrBuilder FortyTwoSplat =64 B.buildSplatBuildVector(v4s64, B.buildConstant(s64, 42));65 int64_t Cst;66 EXPECT_TRUE(mi_match(FortyTwoSplat.getReg(0), *MRI, m_ICstOrSplat(Cst)));67 EXPECT_EQ(Cst, 42);68 69 MachineInstrBuilder NonConstantSplat =70 B.buildBuildVector(v4s64, {Copies[0], Copies[0], Copies[0], Copies[0]});71 EXPECT_FALSE(mi_match(NonConstantSplat.getReg(0), *MRI, m_ICstOrSplat(Cst)));72 73 auto ICst = B.buildConstant(s64, 15).getReg(0);74 auto SmallSplat = B.buildBuildVector(v2s64, {ICst, ICst}).getReg(0);75 auto LargeSplat = B.buildConcatVectors(v4s64, {SmallSplat, SmallSplat});76 EXPECT_TRUE(mi_match(LargeSplat.getReg(0), *MRI, m_ICstOrSplat(Cst)));77}78 79TEST_F(AArch64GISelMITest, MachineInstrPtrBind) {80 setUp();81 if (!TM)82 GTEST_SKIP();83 auto MIBAdd = B.buildAdd(LLT::scalar(64), Copies[0], Copies[1]);84 // Test 'MachineInstr *' bind.85 // Default mi_match.86 MachineInstr *MIPtr = MIBAdd.getInstr();87 bool match = mi_match(MIPtr, *MRI, m_GAdd(m_Reg(), m_Reg()));88 EXPECT_TRUE(match);89 // Specialized mi_match for MachineInstr &.90 MachineInstr &MI = *MIBAdd.getInstr();91 match = mi_match(MI, *MRI, m_GAdd(m_Reg(), m_Reg()));92 EXPECT_TRUE(match);93 // MachineInstrBuilder has automatic conversion to MachineInstr *.94 match = mi_match(MIBAdd, *MRI, m_GAdd(m_Reg(), m_Reg()));95 EXPECT_TRUE(match);96 // Match instruction without def.97 auto MIBBrcond = B.buildBrCond(Copies[0], B.getMBB());98 MachineInstr *MatchedMI;99 match = mi_match(MIBBrcond, *MRI, m_MInstr(MatchedMI));100 EXPECT_TRUE(match);101 EXPECT_TRUE(MIBBrcond.getInstr() == MatchedMI);102 // Match instruction with two defs.103 auto MIBUAddO =104 B.buildUAddo(LLT::scalar(64), LLT::scalar(1), Copies[0], Copies[1]);105 match = mi_match(MIBUAddO, *MRI, m_MInstr(MatchedMI));106 EXPECT_TRUE(match);107 EXPECT_TRUE(MIBUAddO.getInstr() == MatchedMI);108}109 110TEST_F(AArch64GISelMITest, MatchBinaryOp) {111 setUp();112 if (!TM)113 GTEST_SKIP();114 LLT s32 = LLT::scalar(32);115 LLT s64 = LLT::scalar(64);116 LLT p0 = LLT::pointer(0, 64);117 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);118 // Test case for no bind.119 bool match =120 mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg()));121 EXPECT_TRUE(match);122 Register Src0, Src1, Src2;123 match = mi_match(MIBAdd.getReg(0), *MRI,124 m_GAdd(m_Reg(Src0), m_Reg(Src1)));125 EXPECT_TRUE(match);126 EXPECT_EQ(Src0, Copies[0]);127 EXPECT_EQ(Src1, Copies[1]);128 129 // Build MUL(ADD %0, %1), %2130 auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]);131 132 // Try to match MUL.133 match = mi_match(MIBMul.getReg(0), *MRI,134 m_GMul(m_Reg(Src0), m_Reg(Src1)));135 EXPECT_TRUE(match);136 EXPECT_EQ(Src0, MIBAdd.getReg(0));137 EXPECT_EQ(Src1, Copies[2]);138 139 // Try to match MUL(ADD)140 match = mi_match(MIBMul.getReg(0), *MRI,141 m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2)));142 EXPECT_TRUE(match);143 EXPECT_EQ(Src0, Copies[0]);144 EXPECT_EQ(Src1, Copies[1]);145 EXPECT_EQ(Src2, Copies[2]);146 147 // Test Commutativity.148 auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42));149 // Try to match MUL(Cst, Reg) on src of MUL(Reg, Cst) to validate150 // commutativity.151 int64_t Cst;152 match = mi_match(MIBMul2.getReg(0), *MRI,153 m_GMul(m_ICst(Cst), m_Reg(Src0)));154 EXPECT_TRUE(match);155 EXPECT_EQ(Cst, 42);156 EXPECT_EQ(Src0, Copies[0]);157 158 // Make sure commutative doesn't work with something like SUB.159 auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42));160 match = mi_match(MIBSub.getReg(0), *MRI,161 m_GSub(m_ICst(Cst), m_Reg(Src0)));162 EXPECT_FALSE(match);163 164 auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, {s64},165 {Copies[0], B.buildConstant(s64, 42)});166 // Match and test commutativity for FMUL.167 match = mi_match(MIBFMul.getReg(0), *MRI,168 m_GFMul(m_ICst(Cst), m_Reg(Src0)));169 EXPECT_TRUE(match);170 EXPECT_EQ(Cst, 42);171 EXPECT_EQ(Src0, Copies[0]);172 173 // FSUB174 auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, {s64},175 {Copies[0], B.buildConstant(s64, 42)});176 match = mi_match(MIBFSub.getReg(0), *MRI,177 m_GFSub(m_Reg(Src0), m_Reg()));178 EXPECT_TRUE(match);179 EXPECT_EQ(Src0, Copies[0]);180 181 // Build AND %0, %1182 auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);183 // Try to match AND.184 match = mi_match(MIBAnd.getReg(0), *MRI,185 m_GAnd(m_Reg(Src0), m_Reg(Src1)));186 EXPECT_TRUE(match);187 EXPECT_EQ(Src0, Copies[0]);188 EXPECT_EQ(Src1, Copies[1]);189 190 // Build OR %0, %1191 auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);192 // Try to match OR.193 match = mi_match(MIBOr.getReg(0), *MRI,194 m_GOr(m_Reg(Src0), m_Reg(Src1)));195 EXPECT_TRUE(match);196 EXPECT_EQ(Src0, Copies[0]);197 EXPECT_EQ(Src1, Copies[1]);198 199 // Match lshr, and make sure a different shift amount type works.200 auto TruncCopy1 = B.buildTrunc(s32, Copies[1]);201 auto LShr = B.buildLShr(s64, Copies[0], TruncCopy1);202 match = mi_match(LShr.getReg(0), *MRI,203 m_GLShr(m_Reg(Src0), m_Reg(Src1)));204 EXPECT_TRUE(match);205 EXPECT_EQ(Src0, Copies[0]);206 EXPECT_EQ(Src1, TruncCopy1.getReg(0));207 208 // Match shl, and make sure a different shift amount type works.209 auto Shl = B.buildShl(s64, Copies[0], TruncCopy1);210 match = mi_match(Shl.getReg(0), *MRI,211 m_GShl(m_Reg(Src0), m_Reg(Src1)));212 EXPECT_TRUE(match);213 EXPECT_EQ(Src0, Copies[0]);214 EXPECT_EQ(Src1, TruncCopy1.getReg(0));215 216 // Build a G_PTR_ADD and check that we can match it.217 auto PtrAdd = B.buildPtrAdd(p0, {B.buildUndef(p0)}, Copies[0]);218 match = mi_match(PtrAdd.getReg(0), *MRI, m_GPtrAdd(m_Reg(Src0), m_Reg(Src1)));219 EXPECT_TRUE(match);220 EXPECT_EQ(Src0, PtrAdd->getOperand(1).getReg());221 EXPECT_EQ(Src1, Copies[0]);222 223 auto MIBCst = B.buildConstant(s64, 42);224 auto MIBAddCst = B.buildAdd(s64, MIBCst, Copies[0]);225 auto MIBUnmerge = B.buildUnmerge({s32, s32}, B.buildConstant(s64, 42));226 227 // Match min/max, and make sure they're commutative.228 auto SMin = B.buildSMin(s64, Copies[2], MIBAdd);229 EXPECT_TRUE(mi_match(SMin.getReg(0), *MRI,230 m_GSMin(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0))));231 EXPECT_EQ(Src0, Copies[2]);232 EXPECT_EQ(Src1, Copies[0]);233 EXPECT_EQ(Src2, Copies[1]);234 auto SMax = B.buildSMax(s64, Copies[2], MIBAdd);235 EXPECT_TRUE(mi_match(SMax.getReg(0), *MRI,236 m_GSMax(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0))));237 EXPECT_EQ(Src0, Copies[2]);238 EXPECT_EQ(Src1, Copies[0]);239 EXPECT_EQ(Src2, Copies[1]);240 auto UMin = B.buildUMin(s64, Copies[2], MIBAdd);241 EXPECT_TRUE(mi_match(UMin.getReg(0), *MRI,242 m_GUMin(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0))));243 EXPECT_EQ(Src0, Copies[2]);244 EXPECT_EQ(Src1, Copies[0]);245 EXPECT_EQ(Src2, Copies[1]);246 auto UMax = B.buildUMax(s64, Copies[2], MIBAdd);247 EXPECT_TRUE(mi_match(UMax.getReg(0), *MRI,248 m_GUMax(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0))));249 EXPECT_EQ(Src0, Copies[2]);250 EXPECT_EQ(Src1, Copies[0]);251 EXPECT_EQ(Src2, Copies[1]);252 253 // m_BinOp with opcode.254 // Match binary instruction, opcode and its non-commutative operands.255 match = mi_match(MIBAddCst, *MRI,256 m_BinOp(TargetOpcode::G_ADD, m_ICst(Cst), m_Reg(Src0)));257 EXPECT_TRUE(match);258 EXPECT_EQ(Src0, Copies[0]);259 EXPECT_EQ(Cst, 42);260 261 // Opcode doesn't match.262 match = mi_match(MIBAddCst, *MRI,263 m_BinOp(TargetOpcode::G_MUL, m_ICst(Cst), m_Reg(Src0)));264 EXPECT_FALSE(match);265 266 match = mi_match(MIBAddCst, *MRI,267 m_BinOp(TargetOpcode::G_ADD, m_Reg(Src0), m_ICst(Cst)));268 EXPECT_FALSE(match);269 270 // Instruction is not binary.271 match = mi_match(MIBCst, *MRI,272 m_BinOp(TargetOpcode::G_MUL, m_Reg(Src0), m_Reg(Src1)));273 EXPECT_FALSE(match);274 match = mi_match(MIBUnmerge, *MRI,275 m_BinOp(TargetOpcode::G_MUL, m_Reg(Src0), m_Reg(Src1)));276 EXPECT_FALSE(match);277 278 // m_CommutativeBinOp with opcode.279 match = mi_match(280 MIBAddCst, *MRI,281 m_CommutativeBinOp(TargetOpcode::G_ADD, m_ICst(Cst), m_Reg(Src0)));282 EXPECT_TRUE(match);283 EXPECT_EQ(Src0, Copies[0]);284 EXPECT_EQ(Cst, 42);285 286 match = mi_match(287 MIBAddCst, *MRI,288 m_CommutativeBinOp(TargetOpcode::G_MUL, m_ICst(Cst), m_Reg(Src0)));289 EXPECT_FALSE(match);290 291 match = mi_match(292 MIBAddCst, *MRI,293 m_CommutativeBinOp(TargetOpcode::G_ADD, m_Reg(Src0), m_ICst(Cst)));294 EXPECT_TRUE(match);295 EXPECT_EQ(Src0, Copies[0]);296 EXPECT_EQ(Cst, 42);297 298 match = mi_match(299 MIBCst, *MRI,300 m_CommutativeBinOp(TargetOpcode::G_MUL, m_Reg(Src0), m_Reg(Src1)));301 EXPECT_FALSE(match);302 match = mi_match(303 MIBUnmerge, *MRI,304 m_CommutativeBinOp(TargetOpcode::G_MUL, m_Reg(Src0), m_Reg(Src1)));305 EXPECT_FALSE(match);306}307 308TEST_F(AArch64GISelMITest, MatchICmp) {309 setUp();310 if (!TM)311 GTEST_SKIP();312 313 const LLT s1 = LLT::scalar(1);314 auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);315 316 // Check match any predicate.317 bool match =318 mi_match(CmpEq.getReg(0), *MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg()));319 EXPECT_TRUE(match);320 321 // Check we get the predicate and registers.322 CmpInst::Predicate Pred;323 Register Reg0;324 Register Reg1;325 match = mi_match(CmpEq.getReg(0), *MRI,326 m_GICmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));327 EXPECT_TRUE(match);328 EXPECT_EQ(CmpInst::ICMP_EQ, Pred);329 EXPECT_EQ(Copies[0], Reg0);330 EXPECT_EQ(Copies[1], Reg1);331}332 333TEST_F(AArch64GISelMITest, MatchFCmp) {334 setUp();335 if (!TM)336 GTEST_SKIP();337 338 const LLT s1 = LLT::scalar(1);339 auto CmpEq = B.buildFCmp(CmpInst::FCMP_OEQ, s1, Copies[0], Copies[1]);340 341 // Check match any predicate.342 bool match =343 mi_match(CmpEq.getReg(0), *MRI, m_GFCmp(m_Pred(), m_Reg(), m_Reg()));344 EXPECT_TRUE(match);345 346 // Check we get the predicate and registers.347 CmpInst::Predicate Pred;348 Register Reg0;349 Register Reg1;350 match = mi_match(CmpEq.getReg(0), *MRI,351 m_GFCmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));352 EXPECT_TRUE(match);353 EXPECT_EQ(CmpInst::FCMP_OEQ, Pred);354 EXPECT_EQ(Copies[0], Reg0);355 EXPECT_EQ(Copies[1], Reg1);356}357 358TEST_F(AArch64GISelMITest, MatcCommutativeICmp) {359 setUp();360 if (!TM)361 GTEST_SKIP();362 const LLT s1 = LLT::scalar(1);363 Register LHS = Copies[0];364 Register RHS = Copies[1];365 CmpInst::Predicate MatchedPred;366 bool Match = false;367 for (unsigned P = CmpInst::Predicate::FIRST_ICMP_PREDICATE;368 P < CmpInst::Predicate::LAST_ICMP_PREDICATE; ++P) {369 auto CurrPred = static_cast<CmpInst::Predicate>(P);370 auto Cmp = B.buildICmp(CurrPred, s1, LHS, RHS);371 // Basic matching.372 Match = mi_match(373 Cmp.getReg(0), *MRI,374 m_c_GICmp(m_Pred(MatchedPred), m_SpecificReg(LHS), m_SpecificReg(RHS)));375 EXPECT_TRUE(Match);376 EXPECT_EQ(MatchedPred, CurrPred);377 // Commuting operands should still match, but the predicate should be378 // swapped.379 Match = mi_match(380 Cmp.getReg(0), *MRI,381 m_c_GICmp(m_Pred(MatchedPred), m_SpecificReg(RHS), m_SpecificReg(LHS)));382 EXPECT_TRUE(Match);383 EXPECT_EQ(MatchedPred, CmpInst::getSwappedPredicate(CurrPred));384 }385}386 387TEST_F(AArch64GISelMITest, MatcCommutativeFCmp) {388 setUp();389 if (!TM)390 GTEST_SKIP();391 const LLT s1 = LLT::scalar(1);392 Register LHS = Copies[0];393 Register RHS = Copies[1];394 CmpInst::Predicate MatchedPred;395 bool Match = false;396 for (unsigned P = CmpInst::Predicate::FIRST_FCMP_PREDICATE;397 P < CmpInst::Predicate::LAST_FCMP_PREDICATE; ++P) {398 auto CurrPred = static_cast<CmpInst::Predicate>(P);399 auto Cmp = B.buildFCmp(CurrPred, s1, LHS, RHS);400 // Basic matching.401 Match = mi_match(402 Cmp.getReg(0), *MRI,403 m_c_GFCmp(m_Pred(MatchedPred), m_SpecificReg(LHS), m_SpecificReg(RHS)));404 EXPECT_TRUE(Match);405 EXPECT_EQ(MatchedPred, CurrPred);406 // Commuting operands should still match, but the predicate should be407 // swapped.408 Match = mi_match(409 Cmp.getReg(0), *MRI,410 m_c_GFCmp(m_Pred(MatchedPred), m_SpecificReg(RHS), m_SpecificReg(LHS)));411 EXPECT_TRUE(Match);412 EXPECT_EQ(MatchedPred, CmpInst::getSwappedPredicate(CurrPred));413 }414}415 416TEST_F(AArch64GISelMITest, MatchFPUnaryOp) {417 setUp();418 if (!TM)419 GTEST_SKIP();420 421 // Truncate s64 to s32.422 LLT s32 = LLT::scalar(32);423 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);424 425 // Match G_FABS.426 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});427 bool match =428 mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg()));429 EXPECT_TRUE(match);430 431 Register Src;432 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});433 match = mi_match(MIBFNeg.getReg(0), *MRI, m_GFNeg(m_Reg(Src)));434 EXPECT_TRUE(match);435 EXPECT_EQ(Src, Copy0s32.getReg(0));436 437 match = mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg(Src)));438 EXPECT_TRUE(match);439 EXPECT_EQ(Src, Copy0s32.getReg(0));440 441 // Build and match FConstant.442 auto MIBFCst = B.buildFConstant(s32, .5);443 const ConstantFP *TmpFP{};444 match = mi_match(MIBFCst.getReg(0), *MRI, m_GFCst(TmpFP));445 EXPECT_TRUE(match);446 EXPECT_TRUE(TmpFP);447 APFloat APF((float).5);448 auto *CFP = ConstantFP::get(Context, APF);449 EXPECT_EQ(CFP, TmpFP);450 451 // Build double float.452 LLT s64 = LLT::scalar(64);453 auto MIBFCst64 = B.buildFConstant(s64, .5);454 const ConstantFP *TmpFP64{};455 match = mi_match(MIBFCst64.getReg(0), *MRI, m_GFCst(TmpFP64));456 EXPECT_TRUE(match);457 EXPECT_TRUE(TmpFP64);458 APFloat APF64(.5);459 auto CFP64 = ConstantFP::get(Context, APF64);460 EXPECT_EQ(CFP64, TmpFP64);461 EXPECT_NE(TmpFP64, TmpFP);462 463 // Build half float.464 LLT s16 = LLT::scalar(16);465 auto MIBFCst16 = B.buildFConstant(s16, .5);466 const ConstantFP *TmpFP16{};467 match = mi_match(MIBFCst16.getReg(0), *MRI, m_GFCst(TmpFP16));468 EXPECT_TRUE(match);469 EXPECT_TRUE(TmpFP16);470 bool Ignored;471 APFloat APF16(.5);472 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);473 auto CFP16 = ConstantFP::get(Context, APF16);474 EXPECT_EQ(TmpFP16, CFP16);475 EXPECT_NE(TmpFP16, TmpFP);476}477 478TEST_F(AArch64GISelMITest, MatchExtendsTrunc) {479 setUp();480 if (!TM)481 GTEST_SKIP();482 483 LLT s64 = LLT::scalar(64);484 LLT s32 = LLT::scalar(32);485 486 auto MIBTrunc = B.buildTrunc(s32, Copies[0]);487 auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);488 auto MIBZExt = B.buildZExt(s64, MIBTrunc);489 auto MIBSExt = B.buildSExt(s64, MIBTrunc);490 Register Src0;491 bool match =492 mi_match(MIBTrunc.getReg(0), *MRI, m_GTrunc(m_Reg(Src0)));493 EXPECT_TRUE(match);494 EXPECT_EQ(Src0, Copies[0]);495 match =496 mi_match(MIBAExt.getReg(0), *MRI, m_GAnyExt(m_Reg(Src0)));497 EXPECT_TRUE(match);498 EXPECT_EQ(Src0, MIBTrunc.getReg(0));499 500 match = mi_match(MIBSExt.getReg(0), *MRI, m_GSExt(m_Reg(Src0)));501 EXPECT_TRUE(match);502 EXPECT_EQ(Src0, MIBTrunc.getReg(0));503 504 match = mi_match(MIBZExt.getReg(0), *MRI, m_GZExt(m_Reg(Src0)));505 EXPECT_TRUE(match);506 EXPECT_EQ(Src0, MIBTrunc.getReg(0));507 508 // Match ext(trunc src)509 match = mi_match(MIBAExt.getReg(0), *MRI,510 m_GAnyExt(m_GTrunc(m_Reg(Src0))));511 EXPECT_TRUE(match);512 EXPECT_EQ(Src0, Copies[0]);513 514 match = mi_match(MIBSExt.getReg(0), *MRI,515 m_GSExt(m_GTrunc(m_Reg(Src0))));516 EXPECT_TRUE(match);517 EXPECT_EQ(Src0, Copies[0]);518 519 match = mi_match(MIBZExt.getReg(0), *MRI,520 m_GZExt(m_GTrunc(m_Reg(Src0))));521 EXPECT_TRUE(match);522 EXPECT_EQ(Src0, Copies[0]);523}524 525TEST_F(AArch64GISelMITest, MatchSpecificType) {526 setUp();527 if (!TM)528 GTEST_SKIP();529 530 // Try to match a 64bit add.531 LLT s64 = LLT::scalar(64);532 LLT s32 = LLT::scalar(32);533 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);534 EXPECT_FALSE(mi_match(MIBAdd.getReg(0), *MRI,535 m_GAdd(m_SpecificType(s32), m_Reg())));536 EXPECT_TRUE(mi_match(MIBAdd.getReg(0), *MRI,537 m_GAdd(m_SpecificType(s64), m_Reg())));538 539 // Try to match the destination type of a bitcast.540 LLT v2s32 = LLT::fixed_vector(2, 32);541 auto MIBCast = B.buildCast(v2s32, Copies[0]);542 EXPECT_TRUE(543 mi_match(MIBCast.getReg(0), *MRI, m_GBitcast(m_Reg())));544 EXPECT_TRUE(545 mi_match(MIBCast.getReg(0), *MRI, m_SpecificType(v2s32)));546 EXPECT_TRUE(547 mi_match(MIBCast.getReg(1), *MRI, m_SpecificType(s64)));548 549 // Build a PTRToInt and INTTOPTR and match and test them.550 LLT PtrTy = LLT::pointer(0, 64);551 auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);552 auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);553 Register Src0;554 555 // match the ptrtoint(inttoptr reg)556 bool match = mi_match(MIBPtrToInt.getReg(0), *MRI,557 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));558 EXPECT_TRUE(match);559 EXPECT_EQ(Src0, Copies[0]);560}561 562TEST_F(AArch64GISelMITest, MatchCombinators) {563 setUp();564 if (!TM)565 GTEST_SKIP();566 567 LLT s64 = LLT::scalar(64);568 LLT s32 = LLT::scalar(32);569 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);570 Register Src0, Src1;571 bool match =572 mi_match(MIBAdd.getReg(0), *MRI,573 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));574 EXPECT_TRUE(match);575 EXPECT_EQ(Src0, Copies[0]);576 EXPECT_EQ(Src1, Copies[1]);577 // Check for s32 (which should fail).578 match =579 mi_match(MIBAdd.getReg(0), *MRI,580 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));581 EXPECT_FALSE(match);582 match =583 mi_match(MIBAdd.getReg(0), *MRI,584 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));585 EXPECT_TRUE(match);586 EXPECT_EQ(Src0, Copies[0]);587 EXPECT_EQ(Src1, Copies[1]);588 589 // Match a case where none of the predicates hold true.590 match = mi_match(591 MIBAdd.getReg(0), *MRI,592 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));593 EXPECT_FALSE(match);594}595 596TEST_F(AArch64GISelMITest, MatchMiscellaneous) {597 setUp();598 if (!TM)599 GTEST_SKIP();600 601 LLT s64 = LLT::scalar(64);602 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);603 Register Reg = MIBAdd.getReg(0);604 605 // Extract the type.606 LLT Ty;607 EXPECT_TRUE(mi_match(Reg, *MRI, m_GAdd(m_Type(Ty), m_Reg())));608 EXPECT_EQ(Ty, s64);609 610 // Only one use of Reg.611 B.buildCast(LLT::pointer(0, 32), MIBAdd);612 EXPECT_TRUE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))));613 EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg()))));614 615 // Add multiple debug uses of Reg.616 B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg});617 B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg});618 619 EXPECT_FALSE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))));620 EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg()))));621 622 // Multiple non-debug uses of Reg.623 B.buildCast(LLT::pointer(1, 32), MIBAdd);624 EXPECT_FALSE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))));625 EXPECT_FALSE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg()))));626}627 628TEST_F(AArch64GISelMITest, MatchSpecificConstant) {629 setUp();630 if (!TM)631 GTEST_SKIP();632 633 // Basic case: Can we match a G_CONSTANT with a specific value?634 auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);635 EXPECT_TRUE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(42)));636 EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(123)));637 EXPECT_TRUE(638 mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(APInt(64, 42))));639 EXPECT_FALSE(640 mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(APInt(64, 123))));641 642 // Test that this works inside of a more complex pattern.643 LLT s64 = LLT::scalar(64);644 auto MIBAdd = B.buildAdd(s64, Copies[0], FortyTwo);645 EXPECT_TRUE(mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(42)));646 EXPECT_TRUE(mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(APInt(64, 42))));647 648 // Wrong constant.649 EXPECT_FALSE(mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(123)));650 EXPECT_FALSE(651 mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(APInt(64, 123))));652 653 // No constant on the LHS.654 EXPECT_FALSE(mi_match(MIBAdd.getReg(1), *MRI, m_SpecificICst(42)));655 EXPECT_FALSE(mi_match(MIBAdd.getReg(1), *MRI, m_SpecificICst(APInt(64, 42))));656}657 658TEST_F(AArch64GISelMITest, MatchSpecificConstantSplat) {659 setUp();660 if (!TM)661 GTEST_SKIP();662 663 LLT s64 = LLT::scalar(64);664 LLT v4s64 = LLT::fixed_vector(4, s64);665 666 MachineInstrBuilder FortyTwoSplat =667 B.buildSplatBuildVector(v4s64, B.buildConstant(s64, 42));668 MachineInstrBuilder FortyTwo = B.buildConstant(s64, 42);669 670 EXPECT_TRUE(mi_match(FortyTwoSplat.getReg(0), *MRI, m_SpecificICstSplat(42)));671 EXPECT_FALSE(672 mi_match(FortyTwoSplat.getReg(0), *MRI, m_SpecificICstSplat(43)));673 EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICstSplat(42)));674 675 EXPECT_TRUE(mi_match(FortyTwoSplat.getReg(0), *MRI,676 m_SpecificICstSplat(APInt(64, 42))));677 EXPECT_FALSE(mi_match(FortyTwoSplat.getReg(0), *MRI,678 m_SpecificICstSplat(APInt(64, 43))));679 EXPECT_FALSE(680 mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICstSplat(APInt(64, 42))));681 682 MachineInstrBuilder NonConstantSplat =683 B.buildBuildVector(v4s64, {Copies[0], Copies[0], Copies[0], Copies[0]});684 685 MachineInstrBuilder AddSplat =686 B.buildAdd(v4s64, NonConstantSplat, FortyTwoSplat);687 EXPECT_TRUE(mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstSplat(42)));688 EXPECT_FALSE(mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstSplat(43)));689 EXPECT_FALSE(mi_match(AddSplat.getReg(1), *MRI, m_SpecificICstSplat(42)));690 691 EXPECT_TRUE(692 mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstSplat(APInt(64, 42))));693 EXPECT_FALSE(694 mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstSplat(APInt(64, 43))));695 EXPECT_FALSE(696 mi_match(AddSplat.getReg(1), *MRI, m_SpecificICstSplat(APInt(64, 42))));697 698 MachineInstrBuilder Add = B.buildAdd(s64, Copies[0], FortyTwo);699 EXPECT_FALSE(mi_match(Add.getReg(2), *MRI, m_SpecificICstSplat(42)));700 EXPECT_FALSE(701 mi_match(Add.getReg(2), *MRI, m_SpecificICstSplat(APInt(64, 42))));702}703 704TEST_F(AArch64GISelMITest, MatchSpecificConstantOrSplat) {705 setUp();706 if (!TM)707 GTEST_SKIP();708 709 LLT s64 = LLT::scalar(64);710 LLT v4s64 = LLT::fixed_vector(4, s64);711 712 MachineInstrBuilder FortyTwoSplat =713 B.buildSplatBuildVector(v4s64, B.buildConstant(s64, 42));714 MachineInstrBuilder FortyTwo = B.buildConstant(s64, 42);715 716 EXPECT_TRUE(717 mi_match(FortyTwoSplat.getReg(0), *MRI, m_SpecificICstOrSplat(42)));718 EXPECT_FALSE(719 mi_match(FortyTwoSplat.getReg(0), *MRI, m_SpecificICstOrSplat(43)));720 EXPECT_TRUE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICstOrSplat(42)));721 722 EXPECT_TRUE(mi_match(FortyTwoSplat.getReg(0), *MRI,723 m_SpecificICstOrSplat(APInt(64, 42))));724 EXPECT_FALSE(mi_match(FortyTwoSplat.getReg(0), *MRI,725 m_SpecificICstOrSplat(APInt(64, 43))));726 EXPECT_TRUE(727 mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICstOrSplat(APInt(64, 42))));728 729 MachineInstrBuilder NonConstantSplat =730 B.buildBuildVector(v4s64, {Copies[0], Copies[0], Copies[0], Copies[0]});731 732 MachineInstrBuilder AddSplat =733 B.buildAdd(v4s64, NonConstantSplat, FortyTwoSplat);734 EXPECT_TRUE(mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstOrSplat(42)));735 EXPECT_FALSE(mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstOrSplat(43)));736 EXPECT_FALSE(mi_match(AddSplat.getReg(1), *MRI, m_SpecificICstOrSplat(42)));737 738 EXPECT_TRUE(739 mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstOrSplat(APInt(64, 42))));740 EXPECT_FALSE(741 mi_match(AddSplat.getReg(2), *MRI, m_SpecificICstOrSplat(APInt(64, 43))));742 EXPECT_FALSE(743 mi_match(AddSplat.getReg(1), *MRI, m_SpecificICstOrSplat(APInt(64, 42))));744 745 MachineInstrBuilder Add = B.buildAdd(s64, Copies[0], FortyTwo);746 EXPECT_TRUE(mi_match(Add.getReg(2), *MRI, m_SpecificICstOrSplat(42)));747 EXPECT_TRUE(748 mi_match(Add.getReg(2), *MRI, m_SpecificICstOrSplat(APInt(64, 42))));749}750 751TEST_F(AArch64GISelMITest, MatchZeroInt) {752 setUp();753 if (!TM)754 GTEST_SKIP();755 auto Zero = B.buildConstant(LLT::scalar(64), 0);756 EXPECT_TRUE(mi_match(Zero.getReg(0), *MRI, m_ZeroInt()));757 758 auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);759 EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_ZeroInt()));760}761 762TEST_F(AArch64GISelMITest, MatchAllOnesInt) {763 setUp();764 if (!TM)765 GTEST_SKIP();766 auto AllOnes = B.buildConstant(LLT::scalar(64), -1);767 EXPECT_TRUE(mi_match(AllOnes.getReg(0), *MRI, m_AllOnesInt()));768 769 auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);770 EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_AllOnesInt()));771}772 773TEST_F(AArch64GISelMITest, MatchFPOrIntConst) {774 setUp();775 if (!TM)776 GTEST_SKIP();777 778 Register IntOne = B.buildConstant(LLT::scalar(64), 1).getReg(0);779 Register FPOne = B.buildFConstant(LLT::scalar(64), 1.0).getReg(0);780 std::optional<ValueAndVReg> ValReg;781 std::optional<FPValueAndVReg> FValReg;782 783 EXPECT_TRUE(mi_match(IntOne, *MRI, m_GCst(ValReg)));784 EXPECT_EQ(IntOne, ValReg->VReg);785 EXPECT_FALSE(mi_match(IntOne, *MRI, m_GFCst(FValReg)));786 787 EXPECT_FALSE(mi_match(FPOne, *MRI, m_GCst(ValReg)));788 EXPECT_TRUE(mi_match(FPOne, *MRI, m_GFCst(FValReg)));789 EXPECT_EQ(FPOne, FValReg->VReg);790}791 792TEST_F(AArch64GISelMITest, MatchConstantSplat) {793 setUp();794 if (!TM)795 GTEST_SKIP();796 797 LLT s64 = LLT::scalar(64);798 LLT v2s64 = LLT::fixed_vector(2, 64);799 LLT v4s64 = LLT::fixed_vector(4, 64);800 801 Register FPOne = B.buildFConstant(s64, 1.0).getReg(0);802 Register FPZero = B.buildFConstant(s64, 0.0).getReg(0);803 Register Undef = B.buildUndef(s64).getReg(0);804 std::optional<FPValueAndVReg> FValReg;805 806 // GFCstOrSplatGFCstMatch allows undef as part of splat. Undef often comes807 // from padding to legalize into available operation and then ignore added808 // elements e.g. v3s64 to v4s64.809 810 EXPECT_TRUE(mi_match(FPZero, *MRI, GFCstOrSplatGFCstMatch(FValReg)));811 EXPECT_EQ(FPZero, FValReg->VReg);812 813 EXPECT_FALSE(mi_match(Undef, *MRI, GFCstOrSplatGFCstMatch(FValReg)));814 815 auto ZeroSplat = B.buildBuildVector(v4s64, {FPZero, FPZero, FPZero, FPZero});816 EXPECT_TRUE(817 mi_match(ZeroSplat.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));818 EXPECT_EQ(FPZero, FValReg->VReg);819 820 auto ZeroUndef = B.buildBuildVector(v4s64, {FPZero, FPZero, FPZero, Undef});821 EXPECT_TRUE(822 mi_match(ZeroUndef.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));823 EXPECT_EQ(FPZero, FValReg->VReg);824 825 // All undefs are not constant splat.826 auto UndefSplat = B.buildBuildVector(v4s64, {Undef, Undef, Undef, Undef});827 EXPECT_FALSE(828 mi_match(UndefSplat.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));829 830 auto ZeroOne = B.buildBuildVector(v4s64, {FPZero, FPZero, FPZero, FPOne});831 EXPECT_FALSE(832 mi_match(ZeroOne.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));833 834 auto NonConstantSplat =835 B.buildBuildVector(v4s64, {Copies[0], Copies[0], Copies[0], Copies[0]});836 EXPECT_FALSE(mi_match(NonConstantSplat.getReg(0), *MRI,837 GFCstOrSplatGFCstMatch(FValReg)));838 839 auto Mixed = B.buildBuildVector(v4s64, {FPZero, FPZero, FPZero, Copies[0]});840 EXPECT_FALSE(841 mi_match(Mixed.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));842 843 // Look through G_CONCAT_VECTORS.844 auto SmallZeroSplat = B.buildBuildVector(v2s64, {FPZero, FPZero}).getReg(0);845 auto LargeZeroSplat =846 B.buildConcatVectors(v4s64, {SmallZeroSplat, SmallZeroSplat});847 EXPECT_TRUE(mi_match(LargeZeroSplat.getReg(0), *MRI,848 GFCstOrSplatGFCstMatch(FValReg)));849 850 auto SmallZeroSplat2 = B.buildBuildVector(v2s64, {FPZero, FPZero}).getReg(0);851 auto SmallZeroSplat3 = B.buildCopy(v2s64, SmallZeroSplat).getReg(0);852 auto LargeZeroSplat2 =853 B.buildConcatVectors(v4s64, {SmallZeroSplat2, SmallZeroSplat3});854 EXPECT_TRUE(mi_match(LargeZeroSplat2.getReg(0), *MRI,855 GFCstOrSplatGFCstMatch(FValReg)));856 857 // Not all G_CONCAT_VECTORS are splats.858 auto SmallOneSplat = B.buildBuildVector(v2s64, {FPOne, FPOne}).getReg(0);859 auto LargeMixedSplat =860 B.buildConcatVectors(v4s64, {SmallZeroSplat, SmallOneSplat});861 EXPECT_FALSE(mi_match(LargeMixedSplat.getReg(0), *MRI,862 GFCstOrSplatGFCstMatch(FValReg)));863 864 auto SmallMixedSplat = B.buildBuildVector(v2s64, {FPOne, FPZero}).getReg(0);865 auto LargeSplat =866 B.buildConcatVectors(v4s64, {SmallMixedSplat, SmallMixedSplat});867 EXPECT_FALSE(868 mi_match(LargeSplat.getReg(0), *MRI, GFCstOrSplatGFCstMatch(FValReg)));869 870 auto SmallUndefSplat = B.buildBuildVector(v2s64, {Undef, Undef}).getReg(0);871 auto LargeUndefSplat =872 B.buildConcatVectors(v4s64, {SmallUndefSplat, SmallUndefSplat});873 EXPECT_FALSE(mi_match(LargeUndefSplat.getReg(0), *MRI,874 GFCstOrSplatGFCstMatch(FValReg)));875 876 auto UndefVec = B.buildUndef(v2s64).getReg(0);877 auto LargeUndefSplat2 = B.buildConcatVectors(v4s64, {UndefVec, UndefVec});878 EXPECT_FALSE(mi_match(LargeUndefSplat2.getReg(0), *MRI,879 GFCstOrSplatGFCstMatch(FValReg)));880}881 882TEST_F(AArch64GISelMITest, MatchNeg) {883 setUp();884 if (!TM)885 GTEST_SKIP();886 887 LLT s64 = LLT::scalar(64);888 auto Zero = B.buildConstant(LLT::scalar(64), 0);889 auto NegInst = B.buildSub(s64, Zero, Copies[0]);890 Register NegatedReg;891 892 // Match: G_SUB = 0, %Reg893 EXPECT_TRUE(mi_match(NegInst.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));894 EXPECT_EQ(NegatedReg, Copies[0]);895 896 // Don't match: G_SUB = %Reg, 0897 auto NotNegInst1 = B.buildSub(s64, Copies[0], Zero);898 EXPECT_FALSE(mi_match(NotNegInst1.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));899 900 // Don't match: G_SUB = 42, %Reg901 auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);902 auto NotNegInst2 = B.buildSub(s64, FortyTwo, Copies[0]);903 EXPECT_FALSE(mi_match(NotNegInst2.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));904 905 // Complex testcase.906 // %sub = G_SUB = 0, %negated_reg907 // %add = G_ADD = %x, %sub908 auto AddInst = B.buildAdd(s64, Copies[1], NegInst);909 NegatedReg = Register();910 EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Neg(m_Reg(NegatedReg))));911 EXPECT_EQ(NegatedReg, Copies[0]);912}913 914TEST_F(AArch64GISelMITest, MatchNot) {915 setUp();916 if (!TM)917 GTEST_SKIP();918 919 LLT s64 = LLT::scalar(64);920 auto AllOnes = B.buildConstant(LLT::scalar(64), -1);921 auto NotInst1 = B.buildXor(s64, Copies[0], AllOnes);922 Register NotReg;923 924 // Match: G_XOR %NotReg, -1925 EXPECT_TRUE(mi_match(NotInst1.getReg(0), *MRI, m_Not(m_Reg(NotReg))));926 EXPECT_EQ(NotReg, Copies[0]);927 928 // Match: G_XOR -1, %NotReg929 auto NotInst2 = B.buildXor(s64, AllOnes, Copies[1]);930 EXPECT_TRUE(mi_match(NotInst2.getReg(0), *MRI, m_Not(m_Reg(NotReg))));931 EXPECT_EQ(NotReg, Copies[1]);932 933 // Don't match: G_XOR %NotReg, 42934 auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);935 auto WrongCst = B.buildXor(s64, Copies[0], FortyTwo);936 EXPECT_FALSE(mi_match(WrongCst.getReg(0), *MRI, m_Not(m_Reg(NotReg))));937 938 // Complex testcase.939 // %xor = G_XOR %NotReg, -1940 // %add = G_ADD %x, %xor941 auto AddInst = B.buildAdd(s64, Copies[1], NotInst1);942 NotReg = Register();943 EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Not(m_Reg(NotReg))));944 EXPECT_EQ(NotReg, Copies[0]);945}946 947TEST_F(AArch64GISelMITest, MatchSpecificReg) {948 setUp();949 if (!TM)950 GTEST_SKIP();951 auto Cst1 = B.buildConstant(LLT::scalar(64), 42);952 auto Cst2 = B.buildConstant(LLT::scalar(64), 314);953 Register Reg = Cst1.getReg(0);954 // Basic case: Same register twice.955 EXPECT_TRUE(mi_match(Reg, *MRI, m_SpecificReg(Reg)));956 // Basic case: Two explicitly different registers.957 EXPECT_FALSE(mi_match(Reg, *MRI, m_SpecificReg(Cst2.getReg(0))));958 // Check that we can tell that an instruction uses a specific register.959 auto Add = B.buildAdd(LLT::scalar(64), Cst1, Cst2);960 EXPECT_TRUE(mi_match(Add.getReg(0), *MRI, m_GAdd(m_SpecificReg(Reg), m_Reg())));961}962 963TEST_F(AArch64GISelMITest, DeferredMatching) {964 setUp();965 if (!TM)966 GTEST_SKIP();967 auto s64 = LLT::scalar(64);968 auto s32 = LLT::scalar(32);969 970 auto Cst1 = B.buildConstant(s64, 42);971 auto Cst2 = B.buildConstant(s64, 314);972 auto Add = B.buildAdd(s64, Cst1, Cst2);973 auto Sub = B.buildSub(s64, Add, Cst1);974 975 auto TruncAdd = B.buildTrunc(s32, Add);976 auto TruncSub = B.buildTrunc(s32, Sub);977 auto NarrowAdd = B.buildAdd(s32, TruncAdd, TruncSub);978 979 Register X;980 EXPECT_TRUE(mi_match(Sub.getReg(0), *MRI,981 m_GSub(m_GAdd(m_Reg(X), m_Reg()), m_DeferredReg(X))));982 LLT Ty;983 EXPECT_TRUE(984 mi_match(NarrowAdd.getReg(0), *MRI,985 m_GAdd(m_GTrunc(m_Type(Ty)), m_GTrunc(m_DeferredType(Ty)))));986 987 // Test commutative.988 auto Add2 = B.buildAdd(s64, Sub, Cst1);989 EXPECT_TRUE(mi_match(Add2.getReg(0), *MRI,990 m_GAdd(m_Reg(X), m_GSub(m_Reg(), m_DeferredReg(X)))));991}992 993TEST_F(AArch64GISelMITest, AddLike) {994 setUp();995 if (!TM)996 GTEST_SKIP();997 auto s64 = LLT::scalar(64);998 999 auto Cst1 = B.buildConstant(s64, 42);1000 auto Cst2 = B.buildConstant(s64, 314);1001 1002 auto Or1 = B.buildOr(s64, Cst1, Cst2, MachineInstr::Disjoint);1003 auto Or2 = B.buildOr(s64, Cst1, Cst2);1004 auto Add = B.buildAdd(s64, Cst1, Cst2);1005 auto Sub = B.buildSub(s64, Cst1, Cst2);1006 1007 EXPECT_TRUE(mi_match(Or1.getReg(0), *MRI, m_GDisjointOr(m_Reg(), m_Reg())));1008 EXPECT_FALSE(mi_match(Or2.getReg(0), *MRI, m_GDisjointOr(m_Reg(), m_Reg())));1009 1010 EXPECT_TRUE(mi_match(Add.getReg(0), *MRI, m_GAddLike(m_Reg(), m_Reg())));1011 EXPECT_FALSE(mi_match(Sub.getReg(0), *MRI, m_GAddLike(m_Reg(), m_Reg())));1012 EXPECT_TRUE(mi_match(Or1.getReg(0), *MRI, m_GAddLike(m_Reg(), m_Reg())));1013 EXPECT_FALSE(mi_match(Or2.getReg(0), *MRI, m_GAddLike(m_Reg(), m_Reg())));1014}1015 1016} // namespace1017 1018int main(int argc, char **argv) {1019 ::testing::InitGoogleTest(&argc, argv);1020 initLLVM();1021 return RUN_ALL_TESTS();1022}1023