1// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=true -I %p/../../include -I %p/Common -o - | FileCheck %s 2 3include "llvm/Target/Target.td" 4include "GlobalISelEmitterCommon.td" 5 6// Two LOADs with same output size but different input size, hence their 7// GIM_CheckPointerToAny should *not* be merged 8def LOAD8 : I<(outs GPR8:$dst), (ins GPR8:$src), []>; 9def LOAD32 : I<(outs GPR8:$dst), (ins GPR32:$src), []>; 10// CHECK: Label 1: @{{[0-9]+}} 11// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L1_ID:[0-9]+]]*/ [[L1_AT:[0-9]+]], 12// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0, 13// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, 14// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR8RegClassID, 15// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L2_ID:[0-9]+]]*/ [[L2_AT:[0-9]+]], 16// CHECK-NEXT: // MIs[0] src 17// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/8, 18// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR8RegClassID, 19// CHECK-NEXT: // (ld:{ *:[i8] } GPR8:{ *:[i8] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD8:{ *:[i8] } GPR8:{ *:[i8] }:$src) 20// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD8, 21// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 22// CHECK-NEXT: // GIR_Coverage, 0, 23// CHECK-NEXT: GIR_Done, 24// CHECK-NEXT: // Label [[L2_ID]]: @[[L2_AT]] 25// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L3_ID:[0-9]+]]*/ [[L3_AT:[0-9]+]], 26// CHECK-NEXT: // MIs[0] src 27// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32, 28// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 29// CHECK-NEXT: // (ld:{ *:[i8] } GPR32:{ *:[i32] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD32:{ *:[i8] } GPR32:{ *:[i32] }:$src) 30// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD32, 31// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 32// CHECK-NEXT: // GIR_Coverage, 1, 33// CHECK-NEXT: GIR_Done, 34// CHECK-NEXT: // Label [[L3_ID]]: @[[L3_AT]] 35// CHECK-NEXT: GIM_Reject, 36// CHECK-NEXT: // Label [[L1_ID]]: @[[L1_AT]] 37def : Pat<(i8 (load GPR8:$src)), 38 (LOAD8 GPR8:$src)>; 39def : Pat<(i8 (load GPR32:$src)), 40 (LOAD32 GPR32:$src)>; 41 42// Two LOADs with same output size and input size, hence their 43// GIM_CheckPointerToAny *should* be merged 44def S0 : Register<"s0"> { let Namespace = "MyTarget"; } 45def GPR16 : RegisterClass<"MyTarget", [i16], 16, (add S0)>; 46def LOAD16 : I<(outs GPR16:$dst), (ins GPR16:$src), []>; 47def LOAD16Imm : I<(outs GPR16:$dst), (ins GPR16:$src), []>; 48// CHECK: // Label 2: @{{[0-9]+}} 49// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L1_ID:[0-9]+]]*/ [[L1_AT:[0-9]+]], 50// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0, 51// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, 52// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR16RegClassID, 53// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/16, 54// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L2_ID:[0-9]+]]*/ [[L2_AT:[0-9]+]], 55// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 56// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD, 57// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s16, 58// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s16, 59// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR16RegClassID, 60// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/1, /*Op*/2, 10, 61// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 62// CHECK-NEXT: // (ld:{ *:[i16] } (add:{ *:[i16] } GPR16:{ *:[i16] }:$src, 10:{ *:[i16] }))<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD16Imm:{ *:[i16] } GPR16:{ *:[i16] }:$src) 63// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::LOAD16Imm, 64// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 65// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src 66// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, 1, GIU_MergeMemOperands_EndOfList, 67// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, 68// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 69// CHECK-NEXT: // GIR_Coverage, 3, 70// CHECK-NEXT: GIR_Done, 71// CHECK-NEXT: // Label [[L2_ID]]: @[[L2_AT]] 72// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L3_ID:[0-9]+]]*/ [[L3_AT:[0-9]+]], 73// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR16RegClassID, 74// CHECK-NEXT: // (ld:{ *:[i16] } GPR16:{ *:[i16] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD16:{ *:[i16] } GPR16:{ *:[i16] }:$src) 75// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD16, 76// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 77// CHECK-NEXT: // GIR_Coverage, 2, 78// CHECK-NEXT: GIR_Done, 79// CHECK-NEXT: // Label [[L3_ID]]: @[[L3_AT]] 80// CHECK-NEXT: GIM_Reject, 81// CHECK-NEXT: // Label [[L1_ID]]: @[[L1_AT]] 82def : Pat<(i16 (load GPR16:$src)), 83 (LOAD16 GPR16:$src)>; 84def : Pat<(i16 (load (add GPR16:$src, 10))), 85 (LOAD16Imm GPR16:$src)>; 86