Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / TableGen / GlobalISelEmitter-multiple-output.td
blobf75988dadc73b1d1b46693617f59ba3f6a100682
1 // RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -warn-on-skipped-patterns -I %p/../../include -I %p/Common %s -o - < %s | FileCheck %s
3 include "llvm/Target/Target.td"
4 include "GlobalISelEmitterCommon.td"
6 // Test the generation of patterns with multiple output operands and makes sure that
7 // we are able to create a new instruction if necessary, or just simply change the
8 // opcode if the input and output operands of the generic instruction are the same
9 // as the target-specific instruction
11 // Verify that patterns with multiple outputs are translated
13 // Test where only the opcode is mutated during ISel
15 let Constraints = "$ptr_out = $addr" in
16 def LDPost : I<(outs GPR32:$val, GPR32:$ptr_out), (ins GPR32:$addr, GPR32:$off), []>;
17 def SDTLoadPost : SDTypeProfile<2, 2, [
18   SDTCisInt<0>, SDTCisSameAs<1,2>, SDTCisPtrTy<2>, SDTCisInt<3>,
19 ]>;
20 def loadpost : SDNode<"MyTgt::LOADPOST", SDTLoadPost, [
21   SDNPHasChain, SDNPMayLoad, SDNPMemOperand
22 ]>;
23 def G_POST_LOAD : MyTargetGenericInstruction{
24   let OutOperandList = (outs type0:$val, type1:$ptr_out);
25   let InOperandList = (ins type1:$ptr, type2:$off);
27 def : GINodeEquiv<G_POST_LOAD, loadpost>;
28 def : Pat<(loadpost (p0 GPR32:$addr), (i32 GPR32:$off)),
29   (LDPost GPR32:$addr, GPR32:$off)
32 // CHECK:      GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(MyTarget::G_POST_LOAD),
33 // CHECK-NEXT: // MIs[0] DstI[val]
34 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
35 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
36 // CHECK-NEXT: // MIs[0] DstI[ptr_out]
37 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_p0s32,
38 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
39 // CHECK-NEXT: // MIs[0] addr
40 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_p0s32,
41 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
42 // CHECK-NEXT: // MIs[0] off
43 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
44 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/3, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
45 // CHECK-NEXT: // (loadpost:{ *:[i32] }:{ *:[i32] } GPR32:{ *:[i32] }:$addr, GPR32:{ *:[i32] }:$off)  =>  (LDPost:{ *:[i32] }:{ *:[i32] } GPR32:{ *:[i32] }:$addr, GPR32:{ *:[i32] }:$off)
46 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LDPost),
47 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
49 // Test where a whole new MIR instruction is created during ISel
51 def TWO_INS : I<(outs GPR32:$out1, GPR32:$out2), (ins GPR32:$in1, GPR32:$in2), []>;
53 def SDTTwoIn : SDTypeProfile<2, 2, [
54   SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>
55 ]>;
56 def two_in : SDNode<"MyTgt::TWO_IN", SDTTwoIn, []>;
57 def G_TWO_IN : MyTargetGenericInstruction{
58   let OutOperandList = (outs type0:$out1, type0:$out2);
59   let InOperandList = (ins type0:$in1, type0:$in2);
61 def : GINodeEquiv<G_TWO_IN, two_in>;
63 // Swap the input operands for an easy way to force the creation of a new instruction
64 def : Pat<(two_in GPR32:$i1, GPR32:$i2), (TWO_INS GPR32:$i2, GPR32:$i1)>;
66 // CHECK:      GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(MyTarget::G_TWO_IN),
67 // CHECK-NEXT: // MIs[0] DstI[out1]
68 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
69 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
70 // CHECK-NEXT: // MIs[0] DstI[out2]
71 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
72 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
73 // CHECK-NEXT: // MIs[0] i1
74 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
75 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
76 // CHECK-NEXT: // MIs[0] i2
77 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
78 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/3, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
79 // CHECK-NEXT: // (two_in:{ *:[i32] }:{ *:[i32] } GPR32:{ *:[i32] }:$i1, GPR32:{ *:[i32] }:$i2)  =>  (TWO_INS:{ *:[i32] }:{ *:[i32] } GPR32:{ *:[i32] }:$i2, GPR32:{ *:[i32] }:$i1)
80 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::TWO_INS),
81 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // DstI[out1]
82 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // DstI[out2]
83 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/3, // i2
84 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // i1
85 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
86 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,