llvm.org GIT mirror llvm / 25462c0
[GISel]: Make GlobalISelEmitter rule prioritization compatible with selectionDAG This patch changes GlobalISelEmitter to rank patterns similar to how the DAG does it (ie it computes a score for a pattern and adds the added complexity to it). This is so that the decision tree for GISelSelector remains compatible with that of SelectionDAG. https://reviews.llvm.org/D43270 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325401 91177308-0d34-0410-b5e6-96231b3b80d8 Aditya Nandakumar 2 years ago
3 changed file(s) with 544 addition(s) and 505 deletion(s). Raw diff Collapse all Expand all
5151 ; CHECK-LABEL: name: test_blsi32rr_nomatch
5252 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
5353 ; CHECK: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags
54 ; CHECK: [[SUB32ri:%[0-9]+]]:gr32 = SUB32ri [[MOV32r0_]], 0, implicit-def $eflags
54 ; CHECK: [[SUB32ri:%[0-9]+]]:gr32 = SUB32ri8 [[MOV32r0_]], 0, implicit-def $eflags
5555 ; CHECK: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[SUB32ri]], [[COPY]], implicit-def $eflags
5656 ; CHECK: $edi = COPY [[AND32rr]]
5757 %0(s32) = COPY $edi
226226 // CHECK-LABEL: MatchTable0[] = {
227227 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
228228 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
229 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
230 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
231 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
232 // OPT-NEXT: // No instruction predicates
233 // CHECK-NEXT: // MIs[0] dst
234 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
235 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
236 // CHECK-NEXT: // MIs[0] src1
237 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
238 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
239 // CHECK-NEXT: // MIs[0] src2
240 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
241 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
242 // CHECK-NEXT: // MIs[0] src3
243 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
244 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
245 // CHECK-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2, complex:{ *:[i32] }:$src3) => (INSN2:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src2)
246 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
247 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
248 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
249 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
250 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
251 // CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
252 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
253 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
254 // CHECK-NEXT: GIR_Done,
255 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
256
257 def INSN3 : I<(outs GPR32:$dst),
258 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>;
259 def INSN4 : I<(outs GPR32:$scr),
260 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>;
261 def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
262 (select GPR32:$src3,
263 complex:$src4,
264 (complex i32imm:$src5a, i32imm:$src5b))),
265 (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a,
266 (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a,
267 i32imm:$src5b))>;
268
269 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
270 //
271
272229 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
273230 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
274231 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]
318275 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
319276 // CHECK-NEXT: GIR_Done,
320277 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
278
279 def INSN3 : I<(outs GPR32:$dst),
280 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>;
281 def INSN4 : I<(outs GPR32:$scr),
282 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>;
283 def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
284 (select GPR32:$src3,
285 complex:$src4,
286 (complex i32imm:$src5a, i32imm:$src5b))),
287 (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a,
288 (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a,
289 i32imm:$src5b))>;
290
291 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
292 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
293 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
294 // OPT-NEXT: // No instruction predicates
295 // CHECK-NEXT: // MIs[0] dst
296 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
297 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
298 // CHECK-NEXT: // MIs[0] src1
299 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
300 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
301 // CHECK-NEXT: // MIs[0] src2
302 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
303 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
304 // CHECK-NEXT: // MIs[0] src3
305 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
306 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
307 // CHECK-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2, complex:{ *:[i32] }:$src3) => (INSN2:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src2)
308 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
309 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
310 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
311 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
312 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
313 // CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
314 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
315 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
316 // CHECK-NEXT: GIR_Done,
321317 // Closing the G_SELECT group.
322 // OPT-NEXT: GIM_Reject,
323 // OPT-NEXT: GIR_Done,
324 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
318 // OPT-NEXT: // Label 2: @[[LABEL]]
319 // OPT-NEXT: GIM_Reject,
320 // OPT-NEXT: GIR_Done,
321 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
322 // NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
323
324 //===- Test a pattern with ComplexPattern operands. -----------------------===//
325 //
326
327 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
328 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
329 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
330 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
331 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
332 // OPT-NEXT: // No instruction predicates
333 // CHECK-NEXT: // MIs[0] dst
334 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
335 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
336 // CHECK-NEXT: // MIs[0] src1
337 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
338 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
339 // CHECK-NEXT: // MIs[0] src2
340 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
341 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
342 // CHECK-NEXT: // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2)
343 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
344 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
345 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
346 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
347 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
348 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
349 // CHECK-NEXT: GIR_Done,
350 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
351
352 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
353 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;
354
355
356 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
357 //
358
325359
326360 def : GINodeEquiv;
327361 let mayLoad = 1 in {
330364 def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3),
331365 (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;
332366
333 //===- Test a simple pattern with regclass operands. ----------------------===//
334
335 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
336 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
337 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
338 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
339 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
340 // OPT-NEXT: // No instruction predicates
341 // CHECK-NEXT: // MIs[0] dst
342 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
343 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
344 // CHECK-NEXT: // MIs[0] src1
345 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
346 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID
347 // CHECK-NEXT: // MIs[0] src2
348 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
349 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
350 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)
351 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
352 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
353 // CHECK-NEXT: GIR_Done,
354 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
355
356 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
357 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
358
359 //===- Test a pattern with a tied operand in the matcher ------------------===//
360
361 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
362 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
363 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
364 // OPT-NEXT: // No instruction predicates
365 // CHECK-NEXT: // MIs[0] dst
366 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
367 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
368 // CHECK-NEXT: // MIs[0] src{{$}}
369 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
370 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
371 // CHECK-NEXT: // MIs[0] src{{$}}
372 // CHECK-NEXT: GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1,
373 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src)
374 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::DOUBLE,
375 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
376 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
377 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
378 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
379 // CHECK-NEXT: GIR_Done,
380 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
381
382 def DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>;
383
384 //===- Test a simple pattern with ValueType operands. ----------------------===//
385
386 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
387 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
388 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
389 // OPT-NEXT: // No instruction predicates
390 // CHECK-NEXT: // MIs[0] dst
391 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
392 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
393 // CHECK-NEXT: // MIs[0] src1
394 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
395 // CHECK-NEXT: // MIs[0] src2
396 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
397 // CHECK-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
398 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
399 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
400 // CHECK-NEXT: GIR_Done,
401 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
402 // Closing the G_ADD group.
403 // OPT-NEXT: GIM_Reject,
404 // OPT-NEXT: GIR_Done,
405 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
406
407 def : Pat<(add i32:$src1, i32:$src2),
408 (ADD i32:$src1, i32:$src2)>;
409
410 //===- Test a simple pattern with an intrinsic. ---------------------------===//
411 //
412
413 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
414 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
415 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
416 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
417 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
418 // OPT-NEXT: // No instruction predicates
419 // CHECK-NEXT: // MIs[0] dst
420 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
421 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
422 // CHECK-NEXT: // MIs[0] Operand 1
423 // CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
424 // CHECK-NEXT: // MIs[0] src1
425 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
426 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
427 // CHECK-NEXT: // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
428
429 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV,
430 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
431 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1
432 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
433 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
434 // CHECK-NEXT: GIR_Done,
435 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
436 // Closing the G_INTRINSIC group.
437 // OPT-NEXT: GIM_Reject,
438 // OPT-NEXT: GIR_Done,
439 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
440
441 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
442 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;
443
444 //===- Test a nested instruction match. -----------------------------------===//
445
446 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
447 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
448 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
449 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
450 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
451 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
452 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
453 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
454 // OPT-NEXT: // No instruction predicates
455 // CHECK-NEXT: // MIs[0] dst
456 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
457 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
458 // CHECK-NEXT: // MIs[0] Operand 1
459 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
460 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
461 // CHECK-NEXT: // MIs[1] Operand 0
462 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
463 // CHECK-NEXT: // MIs[1] src1
464 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
465 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
466 // CHECK-NEXT: // MIs[1] src2
467 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
468 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
469 // CHECK-NEXT: // MIs[0] src3
470 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
471 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
472 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
473 // CHECK-NEXT: // (mul:{ *:[i32] } (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2), GPR32:{ *:[i32] }:$src3) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
474 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
475 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
476 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
477 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
478 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
479 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
480 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
481 // CHECK-NEXT: GIR_Done,
482 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
483
484 // We also get a second rule by commutativity.
485 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
486 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
487 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
488 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,
489 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
490 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
491 // OPT-NEXT: // No instruction predicates
492 // CHECK-NEXT: // MIs[0] dst
493 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
494 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
495 // CHECK-NEXT: // MIs[0] src3
496 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
497 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
498 // CHECK-NEXT: // MIs[0] Operand 2
499 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
500 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
501 // CHECK-NEXT: // MIs[1] Operand 0
502 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
503 // CHECK-NEXT: // MIs[1] src1
504 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
505 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
506 // CHECK-NEXT: // MIs[1] src2
507 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
508 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
509 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
510 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src3, (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
511 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
512 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
513 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
514 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
515 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
516 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
517 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
518 // CHECK-NEXT: GIR_Done,
519 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
520
521 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
522 [(set GPR32:$dst,
523 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
524 Requires<[HasA]>;
525
526 //===- Test another simple pattern with regclass operands. ----------------===//
527
528 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
529 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC,
530 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
531 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
532 // OPT-NEXT: // No instruction predicates
533 // CHECK-NEXT: // MIs[0] dst
534 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
535 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
536 // CHECK-NEXT: // MIs[0] src1
537 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
538 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
539 // CHECK-NEXT: // MIs[0] src2
540 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
541 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
542 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1)
543 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
544 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
545 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
546 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
547 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
548 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
549 // CHECK-NEXT: GIR_Done,
550 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
551 // Closing the G_MUL group.
552 // OPT-NEXT: GIM_Reject,
553 // OPT-NEXT: GIR_Done,
554 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
555
556 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
557 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
558 Requires<[HasA, HasB, HasC]>;
559
560367 //===- Test a more complex multi-instruction match. -----------------------===//
561368
562 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
563 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
564369 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
565370 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
566371 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
608413 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
609414 // CHECK-NEXT: GIR_Done,
610415 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
416 // Closing the G_SUB group.
417 // OPT-NEXT: GIM_Reject,
418 // OPT-NEXT: GIR_Done,
419 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
611420
612421 def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
613422 [(set GPR32:$dst,
614423 (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>,
615424 Requires<[HasA]>;
616425
617 //===- Test a pattern with ComplexPattern operands. -----------------------===//
426 //===- Test a simple pattern with an intrinsic. ---------------------------===//
618427 //
619428
620 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
621 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
622 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
623 // OPT-NEXT: // No instruction predicates
624 // CHECK-NEXT: // MIs[0] dst
625 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
626 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
627 // CHECK-NEXT: // MIs[0] src1
628 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
629 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
630 // CHECK-NEXT: // MIs[0] src2
631 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
632 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
633 // CHECK-NEXT: // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2)
634 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
635 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
636 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
637 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
638 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
639 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
640 // CHECK-NEXT: GIR_Done,
641 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
642 // Closing the G_SUB group.
643 // OPT-NEXT: GIM_Reject,
644 // OPT-NEXT: GIR_Done,
645 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
646
647 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
648 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;
429 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
430 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
431 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
432 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
433 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
434 // OPT-NEXT: // No instruction predicates
435 // CHECK-NEXT: // MIs[0] dst
436 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
437 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
438 // CHECK-NEXT: // MIs[0] Operand 1
439 // CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
440 // CHECK-NEXT: // MIs[0] src1
441 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
442 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
443 // CHECK-NEXT: // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
444
445 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV,
446 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
447 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1
448 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
449 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
450 // CHECK-NEXT: GIR_Done,
451 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
452 // Closing the G_INTRINSIC group.
453 // OPT-NEXT: GIM_Reject,
454 // OPT-NEXT: GIR_Done,
455 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
456
457 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
458 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;
459
649460
650461 //===- Test a simple pattern with a default operand. ----------------------===//
651462 //
807618 def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
808619 def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
809620
810 //===- Test a COPY_TO_REGCLASS --------------------------------------------===//
811 //
812
813 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
814 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
815 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
816 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
817 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
818 // OPT-NEXT: // No instruction predicates
819 // CHECK-NEXT: // MIs[0] dst
820 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
821 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
822 // CHECK-NEXT: // MIs[0] src1
823 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
824 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
825 // CHECK-NEXT: // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] })
826 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY,
827 // CHECK-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/1,
828 // CHECK-NEXT: GIR_Done,
829 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
830 // Closing the G_BITCAST group.
831 // OPT-NEXT: GIM_Reject,
832 // OPT-NEXT: GIR_Done,
833 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
834
835 def : Pat<(i32 (bitconvert FPR32:$src1)),
836 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;
837
838 //===- Test a simple pattern with just a specific leaf immediate. ---------===//
839
840 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
841 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
842 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
843 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
844 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
845 // OPT-NEXT: // No instruction predicates
846 // CHECK-NEXT: // MIs[0] dst
847 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
848 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
849 // CHECK-NEXT: // MIs[0] Operand 1
850 // CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
851 // CHECK-NEXT: // 1:{ *:[i32] } => (MOV1:{ *:[i32] })
852 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
853 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
854 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
855 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
856 // CHECK-NEXT: GIR_Done,
857 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
858
859 def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
860
861 //===- Test a simple pattern with a leaf immediate and a predicate. -------===//
862
863 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
864 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
865 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
866 // CHECK-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8,
867 // CHECK-NEXT: // MIs[0] dst
868 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
869 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
870 // CHECK-NEXT: // MIs[0] Operand 1
871 // CHECK-NEXT: // No operand predicates
872 // CHECK-NEXT: // (imm:{ *:[i32] })<>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm)
873 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8,
874 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
875 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
876 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
877 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
878 // CHECK-NEXT: GIR_Done,
879 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
880
881 def simm8 : ImmLeaf(Imm); }]>;
882 def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;
883
884 //===- Same again but use an IntImmLeaf. ----------------------------------===//
885
886 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
887 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
888 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
889 // CHECK-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9,
890 // CHECK-NEXT: // MIs[0] dst
891 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
892 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
893 // CHECK-NEXT: // MIs[0] Operand 1
894 // CHECK-NEXT: // No operand predicates
895 // CHECK-NEXT: // (imm:{ *:[i32] })<>:$imm => (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm)
896 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm9,
897 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
898 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
899 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
900 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
901 // CHECK-NEXT: GIR_Done,
902 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
903
904 def simm9 : IntImmLeaf(Imm->getSExtValue()); }]>;
905 def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>;
906
907 //===- Test a simple pattern with just a leaf immediate. ------------------===//
908
909 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
910 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
911 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
912 // OPT-NEXT: // No instruction predicates
913 // CHECK-NEXT: // MIs[0] dst
914 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
915 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
916 // CHECK-NEXT: // MIs[0] Operand 1
917 // CHECK-NEXT: // No operand predicates
918 // CHECK-NEXT: // (imm:{ *:[i32] }):$imm => (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm)
919 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm,
920 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
921 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
922 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
923 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
924 // CHECK-NEXT: GIR_Done,
925 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
926
927 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;
928
929
930 //===- Test a pattern with a custom renderer. -----------------------------===//
931 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
932 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
933 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
934 // CHECK-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_cimm8,
935 // CHECK-NEXT: // MIs[0] dst
936 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
937 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
938 // CHECK-NEXT: // MIs[0] Operand 1
939 // CHECK-NEXT: // No operand predicates
940 // CHECK-NEXT: // (imm:{ *:[i32] })<><>:$imm => (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm))
941 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVcimm8,
942 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
943 // CHECK-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm8, // imm
944 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
945 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
946 // CHECK-NEXT: GIR_Done,
947 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
948 // Closing the G_CONSTANT group.
949 // OPT-NEXT: GIM_Reject,
950 // OPT-NEXT: GIR_Done,
951 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
952 def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$imm)]>;
953
954 //===- Test a simple pattern with a FP immediate and a predicate. ---------===//
955
956 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
957 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
958 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
959 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
960 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
961 // CHECK-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz,
962 // CHECK-NEXT: // MIs[0] dst
963 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
964 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID,
965 // CHECK-NEXT: // MIs[0] Operand 1
966 // CHECK-NEXT: // No operand predicates
967 // CHECK-NEXT: // (fpimm:{ *:[f32] })<>:$imm => (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm)
968 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVfpimmz,
969 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
970 // CHECK-NEXT: GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
971 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
972 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
973 // CHECK-NEXT: GIR_Done,
974 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
975 // Closing the G_FCONSTANT group.
976 // OPT-NEXT: GIM_Reject,
977 // OPT-NEXT: GIR_Done,
978 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
979
980 def fpimmz : FPImmLeafisExactlyValue(0.0); }]>;
981 def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;
982
983 //===- Test a simple pattern with inferred pointer operands. ---------------===//
984
985 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
986 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
987 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
988 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
989 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
990 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
991 // CHECK-NEXT: // MIs[0] dst
992 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
993 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
994 // CHECK-NEXT: // MIs[0] src1
995 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
996 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
997 // CHECK-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<><> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
998 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,
999 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1000 // CHECK-NEXT: GIR_Done,
1001 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
1002 // Closing the G_LOAD group.
1003 // OPT-NEXT: GIM_Reject,
1004 // OPT-NEXT: GIR_Done,
1005 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
1006
1007 def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
1008 [(set GPR32:$dst, (load GPR32:$src1))]>;
1009621
1010622 //===- Test a simple pattern with a sextload -------------------------------===//
1011623
1047659 def SEXTLOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
1048660 [(set GPR32:$dst, (sextloadi16 GPR32:$src1))]>;
1049661
662
663 //===- Test a nested instruction match. -----------------------------------===//
664
665 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
666 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
667 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
668 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
669 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
670 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
671 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
672 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
673 // OPT-NEXT: // No instruction predicates
674 // CHECK-NEXT: // MIs[0] dst
675 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
676 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
677 // CHECK-NEXT: // MIs[0] Operand 1
678 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
679 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
680 // CHECK-NEXT: // MIs[1] Operand 0
681 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
682 // CHECK-NEXT: // MIs[1] src1
683 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
684 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
685 // CHECK-NEXT: // MIs[1] src2
686 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
687 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
688 // CHECK-NEXT: // MIs[0] src3
689 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
690 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
691 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
692 // CHECK-NEXT: // (mul:{ *:[i32] } (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2), GPR32:{ *:[i32] }:$src3) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
693 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
694 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
695 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
696 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
697 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
698 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
699 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
700 // CHECK-NEXT: GIR_Done,
701 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
702
703 // We also get a second rule by commutativity.
704 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
705 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
706 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
707 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,
708 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
709 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
710 // OPT-NEXT: // No instruction predicates
711 // CHECK-NEXT: // MIs[0] dst
712 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
713 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
714 // CHECK-NEXT: // MIs[0] src3
715 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
716 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
717 // CHECK-NEXT: // MIs[0] Operand 2
718 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
719 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
720 // CHECK-NEXT: // MIs[1] Operand 0
721 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
722 // CHECK-NEXT: // MIs[1] src1
723 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
724 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
725 // CHECK-NEXT: // MIs[1] src2
726 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
727 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
728 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
729 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src3, (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
730 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
731 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
732 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
733 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
734 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
735 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
736 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
737 // CHECK-NEXT: GIR_Done,
738 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
739 // Closing the G_MUL group.
740 // OPT-NEXT: GIM_Reject,
741 // OPT-NEXT: GIR_Done,
742 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
743
744 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
745 [(set GPR32:$dst,
746 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
747 Requires<[HasA]>;
748
749 //===- Test a simple pattern with just a specific leaf immediate. ---------===//
750
751 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
752 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
753 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
754 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
755 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
756 // OPT-NEXT: // No instruction predicates
757 // CHECK-NEXT: // MIs[0] dst
758 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
759 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
760 // CHECK-NEXT: // MIs[0] Operand 1
761 // CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
762 // CHECK-NEXT: // 1:{ *:[i32] } => (MOV1:{ *:[i32] })
763 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
764 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
765 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
766 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
767 // CHECK-NEXT: GIR_Done,
768 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
769
770 def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
771
772 //===- Test a simple pattern with a leaf immediate and a predicate. -------===//
773
774 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
775 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
776 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
777 // CHECK-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8,
778 // CHECK-NEXT: // MIs[0] dst
779 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
780 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
781 // CHECK-NEXT: // MIs[0] Operand 1
782 // CHECK-NEXT: // No operand predicates
783 // CHECK-NEXT: // (imm:{ *:[i32] })<>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm)
784 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8,
785 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
786 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
787 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
788 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
789 // CHECK-NEXT: GIR_Done,
790 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
791
792 def simm8 : ImmLeaf(Imm); }]>;
793 def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;
794
795 //===- Same again but use an IntImmLeaf. ----------------------------------===//
796
797 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
798 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
799 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
800 // CHECK-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9,
801 // CHECK-NEXT: // MIs[0] dst
802 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
803 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
804 // CHECK-NEXT: // MIs[0] Operand 1
805 // CHECK-NEXT: // No operand predicates
806 // CHECK-NEXT: // (imm:{ *:[i32] })<>:$imm => (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm)
807 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm9,
808 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
809 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
810 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
811 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
812 // CHECK-NEXT: GIR_Done,
813 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
814
815 def simm9 : IntImmLeaf(Imm->getSExtValue()); }]>;
816 def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>;
817
818 //===- Test a pattern with a custom renderer. -----------------------------===//
819 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
820 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
821 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
822 // CHECK-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_cimm8,
823 // CHECK-NEXT: // MIs[0] dst
824 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
825 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
826 // CHECK-NEXT: // MIs[0] Operand 1
827 // CHECK-NEXT: // No operand predicates
828 // CHECK-NEXT: // (imm:{ *:[i32] })<><>:$imm => (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm))
829 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVcimm8,
830 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
831 // CHECK-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm8, // imm
832 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
833 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
834 // CHECK-NEXT: GIR_Done,
835 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
836 // Closing the G_CONSTANT group.
837 // OPT-NEXT: GIM_Reject,
838 // OPT-NEXT: GIR_Done,
839 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
840 def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$imm)]>;
841
842 //===- Test a simple pattern with a FP immediate and a predicate. ---------===//
843
844 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
845 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
846 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
847 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
848 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
849 // CHECK-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz,
850 // CHECK-NEXT: // MIs[0] dst
851 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
852 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID,
853 // CHECK-NEXT: // MIs[0] Operand 1
854 // CHECK-NEXT: // No operand predicates
855 // CHECK-NEXT: // (fpimm:{ *:[f32] })<>:$imm => (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm)
856 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVfpimmz,
857 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
858 // CHECK-NEXT: GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
859 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
860 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
861 // CHECK-NEXT: GIR_Done,
862 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
863 // Closing the G_FCONSTANT group.
864 // OPT-NEXT: GIM_Reject,
865 // OPT-NEXT: GIR_Done,
866 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
867
868 //===- Test a simple pattern with inferred pointer operands. ---------------===//
869
870 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
871 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
872 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
873 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
874 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
875 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
876 // CHECK-NEXT: // MIs[0] dst
877 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
878 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
879 // CHECK-NEXT: // MIs[0] src1
880 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
881 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
882 // CHECK-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<><> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
883 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,
884 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
885 // CHECK-NEXT: GIR_Done,
886 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
887 // Closing the G_LOAD group.
888 // OPT-NEXT: GIM_Reject,
889 // OPT-NEXT: GIR_Done,
890 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
891
892 def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
893 [(set GPR32:$dst, (load GPR32:$src1))]>;
894
895 //===- Test a simple pattern with regclass operands. ----------------------===//
896
897 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
898 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
899 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
900 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
901 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
902 // OPT-NEXT: // No instruction predicates
903 // CHECK-NEXT: // MIs[0] dst
904 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
905 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
906 // CHECK-NEXT: // MIs[0] src1
907 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
908 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID
909 // CHECK-NEXT: // MIs[0] src2
910 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
911 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
912 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)
913 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
914 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
915 // CHECK-NEXT: GIR_Done,
916 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
917
918
919 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
920 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
921
922 //===- Test a pattern with a tied operand in the matcher ------------------===//
923
924 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
925 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
926 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
927 // OPT-NEXT: // No instruction predicates
928 // CHECK-NEXT: // MIs[0] dst
929 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
930 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
931 // CHECK-NEXT: // MIs[0] src{{$}}
932 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
933 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
934 // CHECK-NEXT: // MIs[0] src{{$}}
935 // CHECK-NEXT: GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1,
936 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src)
937 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::DOUBLE,
938 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
939 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
940 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
941 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
942 // CHECK-NEXT: GIR_Done,
943 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
944
945 def DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>;
946
947 //===- Test a simple pattern with ValueType operands. ----------------------===//
948
949 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
950 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
951 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
952 // OPT-NEXT: // No instruction predicates
953 // CHECK-NEXT: // MIs[0] dst
954 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
955 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
956 // CHECK-NEXT: // MIs[0] src1
957 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
958 // CHECK-NEXT: // MIs[0] src2
959 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
960 // CHECK-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
961 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
962 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
963 // CHECK-NEXT: GIR_Done,
964 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
965 // Closing the G_ADD group.
966 // OPT-NEXT: GIM_Reject,
967 // OPT-NEXT: GIR_Done,
968 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
969 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
970 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
971
972 def : Pat<(add i32:$src1, i32:$src2),
973 (ADD i32:$src1, i32:$src2)>;
974
975
976
977 //===- Test another simple pattern with regclass operands. ----------------===//
978
979 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
980 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC,
981 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
982 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
983 // OPT-NEXT: // No instruction predicates
984 // CHECK-NEXT: // MIs[0] dst
985 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
986 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
987 // CHECK-NEXT: // MIs[0] src1
988 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
989 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
990 // CHECK-NEXT: // MIs[0] src2
991 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
992 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
993 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1)
994 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
995 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
996 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
997 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
998 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
999 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1000 // CHECK-NEXT: GIR_Done,
1001 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
1002 // Closing the G_MUL group.
1003 // OPT-NEXT: GIM_Reject,
1004 // OPT-NEXT: GIR_Done,
1005 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
1006
1007 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
1008 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
1009 Requires<[HasA, HasB, HasC]>;
1010
1011
1012
1013 //===- Test a COPY_TO_REGCLASS --------------------------------------------===//
1014 //
1015
1016 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
1017 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
1018 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1019 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
1020 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
1021 // OPT-NEXT: // No instruction predicates
1022 // CHECK-NEXT: // MIs[0] dst
1023 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1024 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1025 // CHECK-NEXT: // MIs[0] src1
1026 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1027 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
1028 // CHECK-NEXT: // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] })
1029 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY,
1030 // CHECK-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/1,
1031 // CHECK-NEXT: GIR_Done,
1032 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
1033 // Closing the G_BITCAST group.
1034 // OPT-NEXT: GIM_Reject,
1035 // OPT-NEXT: GIR_Done,
1036 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
1037 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
1038 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
1039
1040 def : Pat<(i32 (bitconvert FPR32:$src1)),
1041 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;
1042
1043
1044
1045 //===- Test a simple pattern with just a leaf immediate. ------------------===//
1046
1047 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1048 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
1049 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
1050 // OPT-NEXT: // No instruction predicates
1051 // CHECK-NEXT: // MIs[0] dst
1052 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1053 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1054 // CHECK-NEXT: // MIs[0] Operand 1
1055 // CHECK-NEXT: // No operand predicates
1056 // CHECK-NEXT: // (imm:{ *:[i32] }):$imm => (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm)
1057 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm,
1058 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
1059 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
1060 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
1061 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1062 // CHECK-NEXT: GIR_Done,
1063 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
1064 // OPT-NEXT: GIM_Reject,
1065 // OPT-NEXT: GIR_Done,
1066 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
1067
1068 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;
1069
1070
1071
1072 def fpimmz : FPImmLeafisExactlyValue(0.0); }]>;
1073 def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;
1074
1075
1076
10501077 //===- Test a pattern with an MBB operand. --------------------------------===//
10511078
10521079 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
25932593 /// GISDNodeXFormEquiv.
25942594 DenseMap SDNodeXFormEquivs;
25952595
2596 /// Keep track of Scores of PatternsToMatch similar to how the DAG does.
2597 /// This adds compatibility for RuleMatchers to use this for ordering rules.
2598 DenseMap RuleMatcherScores;
2599
25962600 // Map of predicates to their subtarget features.
25972601 SubtargetFeatureInfoMap SubtargetFeatures;
25982602
33773381
33783382 Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
33793383 // Keep track of the matchers and actions to emit.
3384 int Score = P.getPatternComplexity(CGP);
33803385 RuleMatcher M(P.getSrcRecord()->getLoc());
3386 RuleMatcherScores[M.getRuleID()] = Score;
33813387 M.addAction(llvm::to_string(*P.getSrcPattern()) +
33823388 " => " +
33833389 llvm::to_string(*P.getDstPattern()));
39333939
39343940 std::stable_sort(Rules.begin(), Rules.end(), [&](const RuleMatcher &A,
39353941 const RuleMatcher &B) {
3942 int ScoreA = RuleMatcherScores[A.getRuleID()];
3943 int ScoreB = RuleMatcherScores[B.getRuleID()];
3944 if (ScoreA > ScoreB)
3945 return true;
3946 if (ScoreB > ScoreA)
3947 return false;
39363948 if (A.isHigherPriorityThan(B)) {
39373949 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
39383950 "and less important at "