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