llvm.org GIT mirror llvm / 3921674
GlobalISel: allow multiple types on MachineInstrs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276481 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 3 years ago
9 changed file(s) with 102 addition(s) and 79 deletion(s). Raw diff Collapse all Expand all
107107 /// Type of the instruction in case of a generic opcode.
108108 /// \invariant This must be LLT{} if getOpcode() is not
109109 /// in the range of generic opcodes.
110 LLT Ty;
110 SmallVector Tys;
111111 #endif
112112
113113 MachineInstr(const MachineInstr&) = delete;
186186
187187 /// Set the type of the instruction.
188188 /// \pre getOpcode() is in the range of the generic opcodes.
189 void setType(LLT Ty);
190 LLT getType() const;
189 void setType(LLT Ty, unsigned Idx = 0);
190 LLT getType(int unsigned = 0) const;
191 unsigned getNumTypes() const;
191192
192193 /// Return true if MI is in a bundle (but not the first MI in a bundle).
193194 ///
594594 if (Token.isError() || parseInstruction(OpCode, Flags))
595595 return true;
596596
597 LLT Ty{};
597 SmallVector Tys;
598598 if (isPreISelGenericOpcode(OpCode)) {
599 // For generic opcode, a type is mandatory.
600 auto Loc = Token.location();
601 if (parseLowLevelType(Loc, Ty))
602 return true;
599 // For generic opcode, at least one type is mandatory.
600 expectAndConsume(MIToken::lbrace);
601 do {
602 auto Loc = Token.location();
603 Tys.resize(Tys.size() + 1);
604 if (parseLowLevelType(Loc, Tys[Tys.size() - 1]))
605 return true;
606 } while (consumeIfPresent(MIToken::comma));
607 expectAndConsume(MIToken::rbrace);
603608 }
604609
605610 // Parse the remaining machine operands.
657662 // TODO: Check for extraneous machine operands.
658663 MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
659664 MI->setFlags(Flags);
660 if (Ty.isValid())
661 MI->setType(Ty);
665 if (Tys.size() > 0) {
666 for (unsigned i = 0; i < Tys.size(); ++i)
667 MI->setType(Tys[i], i);
668 }
662669 for (const auto &Operand : Operands)
663670 MI->addOperand(MF, Operand.Operand);
664671 if (assignRegisterTies(*MI, Operands))
565565 OS << TII->getName(MI.getOpcode());
566566 if (isPreISelGenericOpcode(MI.getOpcode())) {
567567 assert(MI.getType().isValid() && "Generic instructions must have a type");
568 OS << ' ';
569 MI.getType().print(OS);
568 OS << " { ";
569 for (unsigned i = 0; i < MI.getNumTypes(); ++i) {
570 MI.getType().print(OS);
571 if (i + 1 != MI.getNumTypes())
572 OS << ", ";
573 }
574 OS << " } ";
570575 }
571576 if (I < E)
572577 OS << ' ';
655655 debugLoc(std::move(dl))
656656 #ifdef LLVM_BUILD_GLOBAL_ISEL
657657 ,
658 Ty(LLT{})
658 Tys(0)
659659 #endif
660660 {
661661 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
679679 MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc())
680680 #ifdef LLVM_BUILD_GLOBAL_ISEL
681681 ,
682 Ty(LLT{})
682 Tys(0)
683683 #endif
684684 {
685685 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
709709 // The proper implementation is WIP and is tracked here:
710710 // PR26576.
711711 #ifndef LLVM_BUILD_GLOBAL_ISEL
712 void MachineInstr::setType(LLT Ty) {}
713
714 LLT MachineInstr::getType() const { return LLT{}; }
712 unsigned MachineInstr::getNumTypes() const { return 0; }
713
714 void MachineInstr::setType(LLT Ty, unsigned Idx) {}
715
716 LLT MachineInstr::getType(unsigned Idx) const { return LLT{}; }
715717
716718 #else
717 void MachineInstr::setType(LLT Ty) {
719 unsigned MachineInstr::getNumTypes() const { return Tys.size(); }
720
721 void MachineInstr::setType(LLT Ty, unsigned Idx) {
718722 assert((!Ty.isValid() || isPreISelGenericOpcode(getOpcode())) &&
719723 "Non generic instructions are not supposed to be typed");
720 this->Ty = Ty;
721 }
722
723 LLT MachineInstr::getType() const { return Ty; }
724 if (Tys.size() < Idx + 1)
725 Tys.resize(Idx+1);
726 Tys[Idx] = Ty;
727 }
728
729 LLT MachineInstr::getType(unsigned Idx) const { return Tys[Idx]; }
724730 #endif // LLVM_BUILD_GLOBAL_ISEL
725731
726732 /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
17231729 else
17241730 OS << "UNKNOWN";
17251731
1726 if (getType().isValid()) {
1727 OS << ' ';
1728 getType().print(OS);
1729 OS << ' ';
1732 if (getNumTypes() > 0) {
1733 OS << " { ";
1734 for (unsigned i = 0; i < getNumTypes(); ++i) {
1735 getType(i).print(OS);
1736 if (i + 1 != getNumTypes())
1737 OS << ", ";
1738 }
1739 OS << " } ";
17301740 }
17311741
17321742 if (SkipOpers)
88 ; CHECK: name: addi64
99 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
1010 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
11 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_ADD s64 [[ARG1]], [[ARG2]]
11 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_ADD { s64 } [[ARG1]], [[ARG2]]
1212 ; CHECK-NEXT: %x0 = COPY [[RES]]
1313 ; CHECK-NEXT: RET_ReallyLR implicit %x0
1414 define i64 @addi64(i64 %arg1, i64 %arg2) {
2222 ; CHECK-NEXT: - { id: 0, name: ptr1, offset: 0, size: 8, alignment: 8 }
2323 ; CHECK-NEXT: - { id: 1, name: ptr2, offset: 0, size: 8, alignment: 1 }
2424 ; CHECK-NEXT: - { id: 2, name: ptr3, offset: 0, size: 128, alignment: 8 }
25 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX p0 0
26 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX p0 1
27 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX p0 2
25 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX { p0 } 0
26 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX { p0 } 1
27 ; CHECK: %{{[0-9]+}}(64) = G_FRAME_INDEX { p0 } 2
2828 define void @allocai64() {
2929 %ptr1 = alloca i64
3030 %ptr2 = alloca i64, align 1
4343 ; CHECK-NEXT: successors: %[[END:[0-9a-zA-Z._-]+]]({{0x[a-f0-9]+ / 0x[a-f0-9]+}} = 100.00%)
4444 ;
4545 ; Check that we emit the correct branch.
46 ; CHECK: G_BR unsized %[[END]]
46 ; CHECK: G_BR { unsized } %[[END]]
4747 ;
4848 ; Check that end contains the return instruction.
4949 ; CHECK: [[END]]:
5858 ; CHECK: name: ori64
5959 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
6060 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
61 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_OR s64 [[ARG1]], [[ARG2]]
61 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_OR { s64 } [[ARG1]], [[ARG2]]
6262 ; CHECK-NEXT: %x0 = COPY [[RES]]
6363 ; CHECK-NEXT: RET_ReallyLR implicit %x0
6464 define i64 @ori64(i64 %arg1, i64 %arg2) {
6969 ; CHECK: name: ori32
7070 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0
7171 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1
72 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_OR s32 [[ARG1]], [[ARG2]]
72 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_OR { s32 } [[ARG1]], [[ARG2]]
7373 ; CHECK-NEXT: %w0 = COPY [[RES]]
7474 ; CHECK-NEXT: RET_ReallyLR implicit %w0
7575 define i32 @ori32(i32 %arg1, i32 %arg2) {
8181 ; CHECK: name: andi64
8282 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
8383 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
84 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_AND s64 [[ARG1]], [[ARG2]]
84 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_AND { s64 } [[ARG1]], [[ARG2]]
8585 ; CHECK-NEXT: %x0 = COPY [[RES]]
8686 ; CHECK-NEXT: RET_ReallyLR implicit %x0
8787 define i64 @andi64(i64 %arg1, i64 %arg2) {
9292 ; CHECK: name: andi32
9393 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0
9494 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1
95 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_AND s32 [[ARG1]], [[ARG2]]
95 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_AND { s32 } [[ARG1]], [[ARG2]]
9696 ; CHECK-NEXT: %w0 = COPY [[RES]]
9797 ; CHECK-NEXT: RET_ReallyLR implicit %w0
9898 define i32 @andi32(i32 %arg1, i32 %arg2) {
104104 ; CHECK: name: subi64
105105 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
106106 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
107 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_SUB s64 [[ARG1]], [[ARG2]]
107 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_SUB { s64 } [[ARG1]], [[ARG2]]
108108 ; CHECK-NEXT: %x0 = COPY [[RES]]
109109 ; CHECK-NEXT: RET_ReallyLR implicit %x0
110110 define i64 @subi64(i64 %arg1, i64 %arg2) {
115115 ; CHECK: name: subi32
116116 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0
117117 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1
118 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SUB s32 [[ARG1]], [[ARG2]]
118 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SUB { s32 } [[ARG1]], [[ARG2]]
119119 ; CHECK-NEXT: %w0 = COPY [[RES]]
120120 ; CHECK-NEXT: RET_ReallyLR implicit %w0
121121 define i32 @subi32(i32 %arg1, i32 %arg2) {
6767 body: |
6868 bb.0.entry:
6969 liveins: %x0
70 ; CHECK: %0(32) = G_ADD s32 %w0
71 %0(32) = G_ADD s32 %w0, %w0
70 ; CHECK: %0(32) = G_ADD { s32 } %w0
71 %0(32) = G_ADD { s32 } %w0, %w0
7272 ...
7373
7474 ---
8484 body: |
8585 bb.0.entry:
8686 liveins: %d0
87 ; CHECK: %0(64) = G_ADD <2 x s32> %d0
88 %0(64) = G_ADD <2 x s32> %d0, %d0
87 ; CHECK: %0(64) = G_ADD { <2 x s32> } %d0
88 %0(64) = G_ADD { <2 x s32> } %d0, %d0
8989 ...
9090
9191 ---
106106 liveins: %s0, %x0
107107 ; CHECK: %0(32) = COPY %s0
108108 ; CHECK-NEXT: %2(32) = COPY %0
109 ; CHECK-NEXT: %1(32) = G_ADD s32 %2, %w0
109 ; CHECK-NEXT: %1(32) = G_ADD { s32 } %2, %w0
110110 %0(32) = COPY %s0
111 %1(32) = G_ADD s32 %0, %w0
111 %1(32) = G_ADD { s32 } %0, %w0
112112 ...
113113
114114 # Check that we repair the assignment for %0 differently for both uses.
128128 ; CHECK: %0(32) = COPY %s0
129129 ; CHECK-NEXT: %2(32) = COPY %0
130130 ; CHECK-NEXT: %3(32) = COPY %0
131 ; CHECK-NEXT: %1(32) = G_ADD s32 %2, %3
131 ; CHECK-NEXT: %1(32) = G_ADD { s32 } %2, %3
132132 %0(32) = COPY %s0
133 %1(32) = G_ADD s32 %0, %0
133 %1(32) = G_ADD { s32 } %0, %0
134134 ...
135135
136136 ---
151151 bb.0.entry:
152152 liveins: %w0
153153 ; CHECK: %0(32) = COPY %w0
154 ; CHECK-NEXT: %2(32) = G_ADD s32 %0, %w0
154 ; CHECK-NEXT: %2(32) = G_ADD { s32 } %0, %w0
155155 ; CHECK-NEXT: %1(32) = COPY %2
156156 %0(32) = COPY %w0
157 %1(32) = G_ADD s32 %0, %w0
157 %1(32) = G_ADD { s32 } %0, %w0
158158 ...
159159
160160 ---
186186
187187 bb.1.then:
188188 successors: %bb.2.end
189 %3(32) = G_ADD s32 %0, %0
189 %3(32) = G_ADD { s32 } %0, %0
190190
191191 bb.2.end:
192192 %4(32) = PHI %0, %bb.0.entry, %3, %bb.1.then
210210 liveins: %w0, %s0
211211 ; CHECK: %0(32) = COPY %w0
212212 ; CHECK-NEXT: %2(32) = COPY %s0
213 ; CHECK-NEXT: %1(32) = G_ADD s32 %0, %2
213 ; CHECK-NEXT: %1(32) = G_ADD { s32 } %0, %2
214214 %0(32) = COPY %w0
215 %1(32) = G_ADD s32 %0, %s0
215 %1(32) = G_ADD { s32 } %0, %s0
216216 ...
217217
218218 ---
228228 bb.0.entry:
229229 liveins: %w0
230230 ; CHECK: %0(32) = COPY %w0
231 ; CHECK-NEXT: %1(32) = G_ADD s32 %0, %0
231 ; CHECK-NEXT: %1(32) = G_ADD { s32 } %0, %0
232232 ; CHECK-NEXT: %s0 = COPY %1
233233 %0(32) = COPY %w0
234 %s0 = G_ADD s32 %0, %0
234 %s0 = G_ADD { s32 } %0, %0
235235 ...
236236
237237 ---
270270 ; FAST-NEXT: %3(64) = COPY %0
271271 ; FAST-NEXT: %4(64) = COPY %1
272272 ; The mapping of G_OR is on FPR.
273 ; FAST-NEXT: %2(64) = G_OR <2 x s32> %3, %4
273 ; FAST-NEXT: %2(64) = G_OR { <2 x s32> } %3, %4
274274
275275 ; Greedy mode remapped the instruction on the GPR bank.
276 ; GREEDY-NEXT: %2(64) = G_OR <2 x s32> %0, %1
276 ; GREEDY-NEXT: %2(64) = G_OR { <2 x s32> } %0, %1
277277 %0(64) = COPY %x0
278278 %1(64) = COPY %x1
279 %2(64) = G_OR <2 x s32> %0, %1
279 %2(64) = G_OR { <2 x s32> } %0, %1
280280 ...
281281
282282 ---
316316 ; FAST-NEXT: %3(64) = COPY %0
317317 ; FAST-NEXT: %4(64) = COPY %1
318318 ; The mapping of G_OR is on FPR.
319 ; FAST-NEXT: %2(64) = G_OR <2 x s32> %3, %4
319 ; FAST-NEXT: %2(64) = G_OR { <2 x s32> } %3, %4
320320
321321 ; Greedy mode remapped the instruction on the GPR bank.
322 ; GREEDY-NEXT: %3(64) = G_OR <2 x s32> %0, %1
322 ; GREEDY-NEXT: %3(64) = G_OR { <2 x s32> } %0, %1
323323 ; We need to keep %2 into FPR because we do not know anything about it.
324324 ; GREEDY-NEXT: %2(64) = COPY %3
325325 %0(64) = COPY %x0
326326 %1(64) = COPY %x1
327 %2(64) = G_OR <2 x s32> %0, %1
328 ...
327 %2(64) = G_OR { <2 x s32> } %0, %1
328 ...
2020 bb.0.entry:
2121 liveins: %q0, %q1, %q2, %q3
2222 ; CHECK-LABEL: name: test_vector_add
23 ; CHECK-DAG: [[LHS_LO:%.*]](128), [[LHS_HI:%.*]](128) = G_EXTRACT <2 x s64> %0, 0, 128
24 ; CHECK-DAG: [[RHS_LO:%.*]](128), [[RHS_HI:%.*]](128) = G_EXTRACT <2 x s64> %1, 0, 128
25 ; CHECK: [[RES_LO:%.*]](128) = G_ADD <2 x s64> [[LHS_LO]], [[RHS_LO]]
26 ; CHECK: [[RES_HI:%.*]](128) = G_ADD <2 x s64> [[LHS_HI]], [[RHS_HI]]
27 ; CHECK: %2(256) = G_SEQUENCE <4 x s64> [[RES_LO]], [[RES_HI]]
23 ; CHECK-DAG: [[LHS_LO:%.*]](128), [[LHS_HI:%.*]](128) = G_EXTRACT { <2 x s64> } %0, 0, 128
24 ; CHECK-DAG: [[RHS_LO:%.*]](128), [[RHS_HI:%.*]](128) = G_EXTRACT { <2 x s64> } %1, 0, 128
25 ; CHECK: [[RES_LO:%.*]](128) = G_ADD { <2 x s64> } [[LHS_LO]], [[RHS_LO]]
26 ; CHECK: [[RES_HI:%.*]](128) = G_ADD { <2 x s64> } [[LHS_HI]], [[RHS_HI]]
27 ; CHECK: %2(256) = G_SEQUENCE { <4 x s64> } [[RES_LO]], [[RES_HI]]
2828
29 %0(256) = G_SEQUENCE <4 x s64> %q0, %q1
30 %1(256) = G_SEQUENCE <4 x s64> %q2, %q3
31 %2(256) = G_ADD <4 x s64> %0, %1
32 %q0, %q1 = G_EXTRACT <2 x s64> %2, 0, 128
29 %0(256) = G_SEQUENCE { <4 x s64> } %q0, %q1
30 %1(256) = G_SEQUENCE { <4 x s64> } %q2, %q3
31 %2(256) = G_ADD { <4 x s64> } %0, %1
32 %q0, %q1 = G_EXTRACT { <2 x s64> } %2, 0, 128
3333 ...
44
55 ; Tests for add.
66 ; CHECK: name: addi32
7 ; CHECK: G_ADD s32
7 ; CHECK: G_ADD { s32 }
88 define i32 @addi32(i32 %arg1, i32 %arg2) {
99 %res = add i32 %arg1, %arg2
1010 ret i32 %res
3232 body: |
3333 bb.0.entry:
3434 liveins: %edi
35 ; CHECK: %0(32) = G_ADD s32 %edi
36 %0(32) = G_ADD s32 %edi, %edi
37 ; CHECK: %1(64) = G_ADD <2 x s32> %edi
38 %1(64) = G_ADD <2 x s32> %edi, %edi
39 ; CHECK: %2(64) = G_ADD s64 %edi
40 %2(64) = G_ADD s64 %edi, %edi
35 ; CHECK: %0(32) = G_ADD { s32 } %edi
36 %0(32) = G_ADD { s32 } %edi, %edi
37 ; CHECK: %1(64) = G_ADD { <2 x s32> } %edi
38 %1(64) = G_ADD { <2 x s32> } %edi, %edi
39 ; CHECK: %2(64) = G_ADD { s64 } %edi
40 %2(64) = G_ADD { s64 } %edi, %edi
4141 ; G_ADD is actually not a valid operand for structure type,
4242 ; but that is the only one we have for now for testing.
43 ; CHECK: %3(64) = G_ADD s64 %edi
44 %3(64) = G_ADD s64 %edi, %edi
45 ; CHECK: %4(48) = G_ADD s48 %edi
46 %4(48) = G_ADD s48 %edi, %edi
43 ; CHECK: %3(64) = G_ADD { s64 } %edi
44 %3(64) = G_ADD { s64 } %edi, %edi
45 ; CHECK: %4(48) = G_ADD { s48 } %edi
46 %4(48) = G_ADD { s48 } %edi, %edi
4747 ...