llvm.org GIT mirror llvm / 9887195
Merging r359898: ------------------------------------------------------------------------ r359898 | arsenm | 2019-05-03 08:21:53 -0700 (Fri, 03 May 2019) | 3 lines AMDGPU: Support shrinking add with FI in SIFoldOperands Avoids test regression in a future patch ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@362648 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 2 months ago
2 changed file(s) with 276 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
200200 Mod.setImm(Mod.getImm() & ~SISrcMods::OP_SEL_1);
201201 }
202202 }
203
204 if (Fold.needsShrink()) {
205 MachineBasicBlock *MBB = MI->getParent();
206 auto Liveness = MBB->computeRegisterLiveness(&TRI, AMDGPU::VCC, MI);
207 if (Liveness != MachineBasicBlock::LQR_Dead)
208 return false;
209
210 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
211 int Op32 = Fold.getShrinkOpcode();
212 MachineOperand &Dst0 = MI->getOperand(0);
213 MachineOperand &Dst1 = MI->getOperand(1);
214 assert(Dst0.isDef() && Dst1.isDef());
215
216 bool HaveNonDbgCarryUse = !MRI.use_nodbg_empty(Dst1.getReg());
217
218 const TargetRegisterClass *Dst0RC = MRI.getRegClass(Dst0.getReg());
219 unsigned NewReg0 = MRI.createVirtualRegister(Dst0RC);
220
221 MachineInstr *Inst32 = TII.buildShrunkInst(*MI, Op32);
222
223 if (HaveNonDbgCarryUse) {
224 BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), Dst1.getReg())
225 .addReg(AMDGPU::VCC, RegState::Kill);
226 }
227
228 // Keep the old instruction around to avoid breaking iterators, but
229 // replace it with a dummy instruction to remove uses.
230 //
231 // FIXME: We should not invert how this pass looks at operands to avoid
232 // this. Should track set of foldable movs instead of looking for uses
233 // when looking at a use.
234 Dst0.setReg(NewReg0);
235 for (unsigned I = MI->getNumOperands() - 1; I > 0; --I)
236 MI->RemoveOperand(I);
237 MI->setDesc(TII.get(AMDGPU::IMPLICIT_DEF));
238
239 if (Fold.isCommuted())
240 TII.commuteInstruction(*Inst32, false);
241 return true;
242 }
243
203 }
204
205 if ((Fold.isImm() || Fold.isFI()) && Fold.needsShrink()) {
206 MachineBasicBlock *MBB = MI->getParent();
207 auto Liveness = MBB->computeRegisterLiveness(&TRI, AMDGPU::VCC, MI);
208 if (Liveness != MachineBasicBlock::LQR_Dead)
209 return false;
210
211 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
212 int Op32 = Fold.getShrinkOpcode();
213 MachineOperand &Dst0 = MI->getOperand(0);
214 MachineOperand &Dst1 = MI->getOperand(1);
215 assert(Dst0.isDef() && Dst1.isDef());
216
217 bool HaveNonDbgCarryUse = !MRI.use_nodbg_empty(Dst1.getReg());
218
219 const TargetRegisterClass *Dst0RC = MRI.getRegClass(Dst0.getReg());
220 unsigned NewReg0 = MRI.createVirtualRegister(Dst0RC);
221
222 MachineInstr *Inst32 = TII.buildShrunkInst(*MI, Op32);
223
224 if (HaveNonDbgCarryUse) {
225 BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), Dst1.getReg())
226 .addReg(AMDGPU::VCC, RegState::Kill);
227 }
228
229 // Keep the old instruction around to avoid breaking iterators, but
230 // replace it with a dummy instruction to remove uses.
231 //
232 // FIXME: We should not invert how this pass looks at operands to avoid
233 // this. Should track set of foldable movs instead of looking for uses
234 // when looking at a use.
235 Dst0.setReg(NewReg0);
236 for (unsigned I = MI->getNumOperands() - 1; I > 0; --I)
237 MI->RemoveOperand(I);
238 MI->setDesc(TII.get(AMDGPU::IMPLICIT_DEF));
239
240 if (Fold.isCommuted())
241 TII.commuteInstruction(*Inst32, false);
242 return true;
243 }
244
245 assert(!Fold.needsShrink() && "not handled");
246
247 if (Fold.isImm()) {
244248 Old.ChangeToImmediate(Fold.ImmToFold);
245249 return true;
246250 }
247
248 assert(!Fold.needsShrink() && "not handled");
249251
250252 if (Fold.isFI()) {
251253 Old.ChangeToFrameIndex(Fold.FrameIndexToFold);
347349 if ((Opc == AMDGPU::V_ADD_I32_e64 ||
348350 Opc == AMDGPU::V_SUB_I32_e64 ||
349351 Opc == AMDGPU::V_SUBREV_I32_e64) && // FIXME
350 OpToFold->isImm()) {
352 (OpToFold->isImm() || OpToFold->isFI())) {
351353 MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
352354
353355 // Verify the other operand is a VGPR, otherwise we would violate the
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass si-fold-operands,dead-mi-elimination %s -o - | FileCheck -check-prefix=GCN %s
2
3 ---
4
5 # First operand is FI is in a VGPR, other operand is a VGPR
6 name: shrink_vgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use
7 tracksRegLiveness: true
8 stack:
9 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
10 body: |
11 bb.0:
12 liveins: $vgpr0
13
14 ; GCN-LABEL: name: shrink_vgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use
15 ; GCN: liveins: $vgpr0
16 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
17 ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
18 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[V_MOV_B32_e32_]], [[COPY]], implicit-def $vcc, implicit $exec
19 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
20 %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
21 %1:vgpr_32 = COPY $vgpr0
22 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
23 S_ENDPGM implicit %2
24
25 ...
26
27 ---
28
29 # First operand is a VGPR, other operand FI is in a VGPR
30 name: shrink_vgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use
31 tracksRegLiveness: true
32 stack:
33 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
34 body: |
35 bb.0:
36 liveins: $vgpr0
37
38 ; GCN-LABEL: name: shrink_vgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use
39 ; GCN: liveins: $vgpr0
40 ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
41 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
42 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[COPY]], [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec
43 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
44 %0:vgpr_32 = COPY $vgpr0
45 %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
46 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
47 S_ENDPGM implicit %2
48
49 ...
50
51 ---
52
53 # First operand is FI is in an SGPR, other operand is a VGPR
54 name: shrink_vgpr_fi_sgpr_v_add_i32_e64_no_carry_out_use
55 tracksRegLiveness: true
56 stack:
57 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
58 body: |
59 bb.0:
60 liveins: $sgpr0
61
62 ; GCN-LABEL: name: shrink_vgpr_fi_sgpr_v_add_i32_e64_no_carry_out_use
63 ; GCN: liveins: $sgpr0
64 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
65 ; GCN: [[COPY:%[0-9]+]]:sreg_32_xm0 = COPY $sgpr0
66 ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 [[COPY]], [[V_MOV_B32_e32_]], implicit $exec
67 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]]
68 %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
69 %1:sreg_32_xm0 = COPY $sgpr0
70 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
71 S_ENDPGM implicit %2
72
73 ...
74
75 ---
76
77 # First operand is an SGPR, other operand FI is in a VGPR
78 name: shrink_sgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use
79 tracksRegLiveness: true
80 stack:
81 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
82 body: |
83 bb.0:
84 liveins: $sgpr0
85
86 ; GCN-LABEL: name: shrink_sgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use
87 ; GCN: liveins: $sgpr0
88 ; GCN: [[COPY:%[0-9]+]]:sreg_32_xm0 = COPY $sgpr0
89 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
90 ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 [[V_MOV_B32_e32_]], [[COPY]], implicit $exec
91 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]]
92 %0:sreg_32_xm0 = COPY $sgpr0
93 %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
94 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
95 S_ENDPGM implicit %2
96
97 ...
98
99 ---
100
101 # First operand is FI is in an SGPR, other operand is a VGPR
102 name: shrink_sgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use
103 tracksRegLiveness: true
104 stack:
105 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
106 body: |
107 bb.0:
108 liveins: $vgpr0
109
110 ; GCN-LABEL: name: shrink_sgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use
111 ; GCN: liveins: $vgpr0
112 ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 %stack.0
113 ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
114 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[S_MOV_B32_]], [[COPY]], implicit-def $vcc, implicit $exec
115 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
116 %0:sreg_32_xm0 = S_MOV_B32 %stack.0
117 %1:vgpr_32 = COPY $vgpr0
118 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
119 S_ENDPGM implicit %2
120
121 ...
122
123 ---
124
125 # First operand is a VGPR, other operand FI is in an SGPR
126 name: shrink_vgpr_sgpr_fi_v_add_i32_e64_no_carry_out_use
127 tracksRegLiveness: true
128 stack:
129 - { id: 0, type: default, offset: 0, size: 64, alignment: 16}
130 body: |
131 bb.0:
132 liveins: $vgpr0
133
134 ; GCN-LABEL: name: shrink_vgpr_sgpr_fi_v_add_i32_e64_no_carry_out_use
135 ; GCN: liveins: $vgpr0
136 ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
137 ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 %stack.0
138 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[S_MOV_B32_]], [[COPY]], implicit-def $vcc, implicit $exec
139 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
140 %0:vgpr_32 = COPY $vgpr0
141 %1:sreg_32_xm0 = S_MOV_B32 %stack.0
142 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
143 S_ENDPGM implicit %2
144
145 ...
146
147 ---
148
149 # First operand is FI is in a VGPR, other operand is an inline imm in a VGPR
150 name: shrink_vgpr_imm_fi_vgpr_v_add_i32_e64_no_carry_out_use
151 tracksRegLiveness: true
152 stack:
153 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
154 body: |
155 bb.0:
156
157 ; GCN-LABEL: name: shrink_vgpr_imm_fi_vgpr_v_add_i32_e64_no_carry_out_use
158 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
159 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 16, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec
160 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
161 %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
162 %1:vgpr_32 = V_MOV_B32_e32 16, implicit $exec
163 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
164 S_ENDPGM implicit %2
165
166 ...
167
168 ---
169
170 # First operand is an inline imm in a VGPR, other operand FI is in a VGPR
171 name: shrink_vgpr_imm_vgpr_fi_v_add_i32_e64_no_carry_out_use
172 tracksRegLiveness: true
173 stack:
174 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
175 body: |
176 bb.0:
177
178 ; GCN-LABEL: name: shrink_vgpr_imm_vgpr_fi_v_add_i32_e64_no_carry_out_use
179 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
180 ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 16, [[V_MOV_B32_e32_]], implicit $exec
181 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]]
182 %0:vgpr_32 = V_MOV_B32_e32 16, implicit $exec
183 %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
184 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
185 S_ENDPGM implicit %2
186
187 ...
188
189 ---
190
191 # First operand is FI is in a VGPR, other operand is an literal constant in a VGPR
192 name: shrink_vgpr_k_fi_vgpr_v_add_i32_e64_no_carry_out_use
193 tracksRegLiveness: true
194 stack:
195 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
196 body: |
197 bb.0:
198
199 ; GCN-LABEL: name: shrink_vgpr_k_fi_vgpr_v_add_i32_e64_no_carry_out_use
200 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
201 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 1234, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec
202 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
203 %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
204 %1:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec
205 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
206 S_ENDPGM implicit %2
207
208 ...
209
210 ---
211
212 # First operand is a literal constant in a VGPR, other operand FI is in a VGPR
213 name: shrink_vgpr_k_vgpr_fi_v_add_i32_e64_no_carry_out_use
214 tracksRegLiveness: true
215 stack:
216 - { id: 0, type: default, offset: 0, size: 64, alignment: 16 }
217 body: |
218 bb.0:
219
220 ; GCN-LABEL: name: shrink_vgpr_k_vgpr_fi_v_add_i32_e64_no_carry_out_use
221 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec
222 ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 %stack.0, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec
223 ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]]
224 %0:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec
225 %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
226 %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec
227 S_ENDPGM implicit %2
228
229 ...