1 /*
2 * Copyright © 2020 Google, Inc.
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include <stdlib.h>
7
8 #include "util/ralloc.h"
9
10 #include "instr-a3xx.h"
11 #include "ir3.h"
12 #include "ir3_compiler.h"
13
14 struct ir3_validate_ctx {
15 struct ir3 *ir;
16
17 /* Current block being validated: */
18 struct ir3_block *current_block;
19
20 /* Current instruction being validated: */
21 struct ir3_instruction *current_instr;
22
23 /* Set of instructions found so far, used to validate that we
24 * don't have SSA uses that occure before def's
25 */
26 struct set *defs;
27 };
28
29 static void
validate_error(struct ir3_validate_ctx * ctx,const char * condstr,const char * file,unsigned line)30 validate_error(struct ir3_validate_ctx *ctx, const char *condstr,
31 const char *file, unsigned line)
32 {
33 fprintf(stderr, "validation fail at %s:%u: %s\n", file, line, condstr);
34 if (ctx->current_instr) {
35 fprintf(stderr, " -> for instruction: ");
36 ir3_print_instr(ctx->current_instr);
37 } else {
38 fprintf(stderr, " -> for block%u\n", block_id(ctx->current_block));
39 }
40 abort();
41 }
42
43 #define validate_assert(ctx, cond) \
44 do { \
45 if (!(cond)) { \
46 validate_error(ctx, #cond, __FILE__, __LINE__); \
47 } \
48 } while (0)
49
50 static unsigned
reg_class_flags(struct ir3_register * reg)51 reg_class_flags(struct ir3_register *reg)
52 {
53 return reg->flags & (IR3_REG_HALF | IR3_REG_SHARED | IR3_REG_PREDICATE);
54 }
55
56 static void
validate_reg(struct ir3_validate_ctx * ctx,struct ir3_register * reg)57 validate_reg(struct ir3_validate_ctx *ctx, struct ir3_register *reg)
58 {
59 if ((reg->flags & IR3_REG_SHARED) && reg->num != INVALID_REG) {
60 validate_assert(ctx, reg->num >= SHARED_REG_START);
61 validate_assert(ctx, reg->num - SHARED_REG_START < SHARED_REG_SIZE);
62 }
63 }
64
65 static void
validate_src(struct ir3_validate_ctx * ctx,struct ir3_instruction * instr,struct ir3_register * reg)66 validate_src(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr,
67 struct ir3_register *reg)
68 {
69 if ((reg->flags & IR3_REG_IMMED) && !(reg->flags & IR3_REG_ALIAS))
70 validate_assert(ctx, ir3_valid_immediate(instr, reg->iim_val));
71
72 if (reg->flags & IR3_REG_FIRST_ALIAS)
73 validate_assert(ctx, reg->flags & IR3_REG_ALIAS);
74
75 if (reg->flags & IR3_REG_ALIAS) {
76 unsigned valid_flags = IR3_REG_ALIAS | IR3_REG_FIRST_ALIAS |
77 IR3_REG_HALF | IR3_REG_CONST | IR3_REG_IMMED |
78 IR3_REG_SSA | IR3_REG_KILL | IR3_REG_FIRST_KILL;
79 validate_assert(ctx, !(reg->flags & ~valid_flags));
80 }
81
82 if (instr->opc == OPC_ALIAS && instr->cat7.alias_scope == ALIAS_RT) {
83 unsigned valid_flags = IR3_REG_HALF | IR3_REG_CONST | IR3_REG_IMMED;
84 validate_assert(ctx, !(reg->flags & ~valid_flags));
85 }
86
87 if (!(reg->flags & IR3_REG_SSA) || !reg->def)
88 return;
89
90 if (reg->flags & IR3_REG_PREDICATE)
91 validate_assert(ctx, !(reg->flags & (IR3_REG_SHARED | IR3_REG_HALF)));
92
93 struct ir3_register *src = reg->def;
94
95 validate_assert(ctx, _mesa_set_search(ctx->defs, src->instr));
96
97 if (src->instr->opc == OPC_META_COLLECT) {
98 /* We only support reading a subset of written components from collects.
99 */
100 validate_assert(ctx, !(reg->wrmask & ~src->wrmask));
101 } else {
102 validate_assert(ctx, src->wrmask == reg->wrmask);
103 }
104
105 validate_assert(ctx, reg_class_flags(src) == reg_class_flags(reg));
106
107 if (src->flags & IR3_REG_CONST)
108 validate_assert(ctx, !(src->flags & IR3_REG_SHARED));
109
110 if (reg->tied) {
111 validate_assert(ctx, reg->tied->tied == reg);
112 validate_assert(ctx, reg_class_flags(reg) == reg_class_flags(reg->tied));
113 validate_assert(ctx, !(reg->flags & (IR3_REG_CONST | IR3_REG_IMMED)));
114 bool found = false;
115 foreach_dst (dst, instr) {
116 if (dst == reg->tied) {
117 found = true;
118 break;
119 }
120 }
121 validate_assert(ctx,
122 found && "tied register not in the same instruction");
123 }
124
125 validate_reg(ctx, reg);
126 }
127
128 /* phi sources are logically read at the end of the predecessor basic block,
129 * and we have to validate them then in order to correctly validate that the
130 * use comes after the definition for loop phis.
131 */
132 static void
validate_phi_src(struct ir3_validate_ctx * ctx,struct ir3_block * block,struct ir3_block * pred)133 validate_phi_src(struct ir3_validate_ctx *ctx, struct ir3_block *block,
134 struct ir3_block *pred)
135 {
136 unsigned pred_idx = ir3_block_get_pred_index(block, pred);
137
138 foreach_instr (phi, &block->instr_list) {
139 if (phi->opc != OPC_META_PHI)
140 break;
141
142 ctx->current_instr = phi;
143 validate_assert(ctx, phi->srcs_count == block->predecessors_count);
144 validate_src(ctx, phi, phi->srcs[pred_idx]);
145 }
146 }
147
148 static void
validate_phi(struct ir3_validate_ctx * ctx,struct ir3_instruction * phi)149 validate_phi(struct ir3_validate_ctx *ctx, struct ir3_instruction *phi)
150 {
151 _mesa_set_add(ctx->defs, phi);
152 validate_assert(ctx, phi->dsts_count == 1);
153 validate_assert(ctx, is_dest_gpr(phi->dsts[0]));
154 }
155
156 static void
validate_dst(struct ir3_validate_ctx * ctx,struct ir3_instruction * instr,struct ir3_register * reg)157 validate_dst(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr,
158 struct ir3_register *reg)
159 {
160 if (reg->flags & IR3_REG_RT) {
161 validate_assert(ctx, instr->opc == OPC_ALIAS);
162 validate_assert(ctx, instr->cat7.alias_scope == ALIAS_RT);
163 validate_assert(ctx, !(reg->flags & ~IR3_REG_RT));
164 validate_assert(ctx, !reg->tied);
165 }
166
167 if (reg->tied) {
168 validate_assert(ctx, reg->tied->tied == reg);
169 validate_assert(ctx, reg_class_flags(reg->tied) == reg_class_flags(reg));
170 validate_assert(ctx, reg->tied->wrmask == reg->wrmask);
171 if (reg->flags & IR3_REG_ARRAY) {
172 validate_assert(ctx, reg->tied->array.base == reg->array.base);
173 validate_assert(ctx, reg->tied->size == reg->size);
174 }
175 bool found = false;
176 foreach_src (src, instr) {
177 if (src == reg->tied) {
178 found = true;
179 break;
180 }
181 }
182 validate_assert(ctx,
183 found && "tied register not in the same instruction");
184 }
185
186 if (reg->flags & IR3_REG_SSA)
187 validate_assert(ctx, reg->instr == instr);
188
189 if (reg->flags & IR3_REG_RELATIV)
190 validate_assert(ctx, instr->address);
191
192 validate_reg(ctx, reg);
193 }
194
195 #define validate_reg_size(ctx, reg, type) \
196 validate_assert( \
197 ctx, (type_size(type) <= 16) == !!((reg)->flags & IR3_REG_HALF))
198
199 static bool
block_contains(struct ir3_block * block,struct ir3_instruction * instr)200 block_contains(struct ir3_block *block, struct ir3_instruction *instr)
201 {
202 foreach_instr (block_instr, &block->instr_list) {
203 if (block_instr == instr)
204 return true;
205 }
206
207 return false;
208 }
209
210 static void
validate_rpt(struct ir3_validate_ctx * ctx,struct ir3_instruction * instr)211 validate_rpt(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr)
212 {
213 if (ir3_instr_is_first_rpt(instr)) {
214 /* All instructions in a repeat group should be in the same block as the
215 * first one.
216 */
217 foreach_instr_rpt (rpt, instr) {
218 validate_assert(ctx, rpt->block == instr->block);
219
220 /* Validate that the block actually contains the repeat. This would
221 * fail if, for example, list_delinit is called instead of
222 * ir3_instr_remove.
223 */
224 validate_assert(ctx, block_contains(instr->block, rpt));
225 }
226 } else if (instr->repeat) {
227 validate_assert(ctx, ir3_supports_rpt(ctx->ir->compiler, instr->opc));
228 validate_assert(ctx, !instr->nop);
229 }
230 }
231
232 static void
validate_instr(struct ir3_validate_ctx * ctx,struct ir3_instruction * instr)233 validate_instr(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr)
234 {
235 struct ir3_register *last_reg = NULL;
236
237 validate_rpt(ctx, instr);
238
239 /* Use alias-group-aware iterator to make sure the src number will be the
240 * same with and without alias groups.
241 */
242 foreach_src_with_alias_n (reg, n, _, instr) {
243 if (reg->flags & IR3_REG_RELATIV)
244 validate_assert(ctx, instr->address);
245
246 validate_src(ctx, instr, reg);
247
248 /* Validate that all src's are either half of full.
249 *
250 * Note: tex instructions w/ .s2en are a bit special in that the
251 * tex/samp src reg is half-reg for non-bindless and full for
252 * bindless, irrespective of the precision of other srcs. The
253 * tex/samp src is the first src reg when .s2en is set
254 */
255 if (reg->tied) {
256 /* must have the same size as the destination, handled in
257 * validate_reg().
258 */
259 } else if (reg == instr->address) {
260 validate_assert(ctx, reg->flags & IR3_REG_HALF);
261 } else if ((instr->flags & IR3_INSTR_S2EN) && (n < 2)) {
262 if (n == 0) {
263 if (instr->flags & IR3_INSTR_B)
264 validate_assert(ctx, !(reg->flags & IR3_REG_HALF));
265 else
266 validate_assert(ctx, reg->flags & IR3_REG_HALF);
267 }
268 } else if (opc_cat(instr->opc) == 1 || opc_cat(instr->opc) == 6) {
269 /* handled below */
270 } else if (opc_cat(instr->opc) == 0) {
271 /* end/chmask/etc are allowed to have different size sources */
272 } else if (instr->opc == OPC_META_PARALLEL_COPY) {
273 /* pcopy sources have to match with their destination but can have
274 * different sizes from each other.
275 */
276 } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO ||
277 instr->opc == OPC_READ_FIRST_MACRO ||
278 instr->opc == OPC_READ_GETLAST_MACRO ||
279 instr->opc == OPC_READ_COND_MACRO) {
280 /* nothing yet */
281 } else if (n > 0) {
282 validate_assert(ctx, (last_reg->flags & IR3_REG_HALF) ==
283 (reg->flags & IR3_REG_HALF));
284 }
285
286 if (is_scalar_alu(instr, ctx->ir->compiler) && reg != instr->address)
287 validate_assert(ctx, reg->flags & (IR3_REG_SHARED | IR3_REG_IMMED |
288 IR3_REG_CONST));
289
290 last_reg = reg;
291 }
292
293 for (unsigned i = 0; i < instr->dsts_count; i++) {
294 struct ir3_register *reg = instr->dsts[i];
295
296 validate_dst(ctx, instr, reg);
297 }
298
299 _mesa_set_add(ctx->defs, instr);
300
301 if ((opc_cat(instr->opc) == 2 || opc_cat(instr->opc) == 3 ||
302 opc_cat(instr->opc) == 4)) {
303 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_SHARED) ||
304 ctx->ir->compiler->has_scalar_alu);
305 }
306
307 /* Check that src/dst types match the register types, and for
308 * instructions that have different opcodes depending on type,
309 * that the opcodes are correct.
310 */
311 switch (opc_cat(instr->opc)) {
312 case 1: /* move instructions */
313 if (instr->opc == OPC_MOVMSK || instr->opc == OPC_BALLOT_MACRO) {
314 validate_assert(ctx, instr->dsts_count == 1);
315 validate_assert(ctx, instr->dsts[0]->flags & IR3_REG_SHARED);
316 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
317 validate_assert(
318 ctx, util_is_power_of_two_or_zero(instr->dsts[0]->wrmask + 1));
319 } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO ||
320 instr->opc == OPC_READ_FIRST_MACRO ||
321 instr->opc == OPC_READ_GETLAST_MACRO ||
322 instr->opc == OPC_READ_COND_MACRO) {
323 /* nothing yet */
324 } else if (instr->opc == OPC_ELECT_MACRO || instr->opc == OPC_SHPS_MACRO) {
325 validate_assert(ctx, instr->dsts_count == 1);
326 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_SHARED));
327 } else if (instr->opc == OPC_SCAN_MACRO) {
328 validate_assert(ctx, instr->dsts_count == 3);
329 validate_assert(ctx, instr->srcs_count == 2);
330 validate_assert(ctx, reg_class_flags(instr->dsts[0]) ==
331 reg_class_flags(instr->srcs[0]));
332 validate_assert(ctx, reg_class_flags(instr->dsts[1]) ==
333 reg_class_flags(instr->srcs[0]));
334 validate_assert(ctx, reg_class_flags(instr->dsts[2]) == IR3_REG_SHARED);
335 } else if (instr->opc == OPC_SCAN_CLUSTERS_MACRO) {
336 validate_assert(ctx, instr->dsts_count >= 2 && instr->dsts_count < 5);
337 validate_assert(ctx, instr->srcs_count >= 2 && instr->srcs_count < 4);
338 validate_assert(ctx,
339 reg_class_flags(instr->dsts[0]) == IR3_REG_SHARED);
340 validate_assert(ctx, reg_class_flags(instr->dsts[1]) ==
341 reg_class_flags(instr->srcs[1]));
342
343 /* exclusive scan */
344 if (instr->srcs_count == 3) {
345 validate_assert(ctx, instr->dsts_count >= 3);
346 validate_assert(ctx, reg_class_flags(instr->srcs[2]) ==
347 reg_class_flags(instr->srcs[1]));
348 validate_assert(ctx, reg_class_flags(instr->dsts[2]) ==
349 reg_class_flags(instr->srcs[1]));
350 }
351
352 /* scratch register */
353 validate_assert(ctx,
354 reg_class_flags(instr->dsts[instr->dsts_count - 1]) ==
355 reg_class_flags(instr->srcs[1]));
356 } else {
357 foreach_dst (dst, instr)
358 validate_reg_size(ctx, dst, instr->cat1.dst_type);
359 foreach_src (src, instr) {
360 if (!src->tied && src != instr->address)
361 validate_reg_size(ctx, src, instr->cat1.src_type);
362 }
363
364 switch (instr->opc) {
365 case OPC_SWZ:
366 validate_assert(ctx, instr->srcs_count == 2);
367 validate_assert(ctx, instr->dsts_count == 2);
368 break;
369 case OPC_GAT:
370 validate_assert(ctx, instr->srcs_count == 4);
371 validate_assert(ctx, instr->dsts_count == 1);
372 break;
373 case OPC_SCT:
374 validate_assert(ctx, instr->srcs_count == 1);
375 validate_assert(ctx, instr->dsts_count == 4);
376 break;
377 default:
378 break;
379 }
380 }
381
382 if (instr->opc != OPC_MOV)
383 validate_assert(ctx, !instr->address);
384
385 break;
386 case 3:
387 switch (instr->opc) {
388 case OPC_MAD_S24:
389 case OPC_MAD_U24:
390 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
391 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
392 break;
393 default:
394 break;
395 }
396 /* Validate that cat3 opc matches the src type. We've already checked
397 * that all the src regs are same type
398 */
399 if (instr->srcs[0]->flags & IR3_REG_HALF) {
400 validate_assert(ctx, instr->opc == cat3_half_opc(instr->opc));
401 } else {
402 validate_assert(ctx, instr->opc == cat3_full_opc(instr->opc));
403 }
404 break;
405 case 4:
406 /* Validate that cat4 opc matches the dst type: */
407 if (instr->dsts[0]->flags & IR3_REG_HALF) {
408 validate_assert(ctx, instr->opc == cat4_half_opc(instr->opc));
409 } else {
410 validate_assert(ctx, instr->opc == cat4_full_opc(instr->opc));
411 }
412 break;
413 case 5:
414 validate_reg_size(ctx, instr->dsts[0], instr->cat5.type);
415 break;
416 case 6:
417 switch (instr->opc) {
418 case OPC_RESINFO:
419 case OPC_RESFMT:
420 if (instr->dsts_count > 0)
421 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
422 validate_reg_size(ctx, instr->srcs[0], instr->cat6.type);
423 break;
424 case OPC_L2G:
425 case OPC_G2L:
426 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
427 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
428 break;
429 case OPC_STG:
430 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
431 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
432 validate_reg_size(ctx, instr->srcs[2], instr->cat6.type);
433 validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
434 break;
435 case OPC_STG_A:
436 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
437 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
438 validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
439 validate_reg_size(ctx, instr->srcs[4], instr->cat6.type);
440 validate_assert(ctx, !(instr->srcs[5]->flags & IR3_REG_HALF));
441 break;
442 case OPC_STL:
443 case OPC_STP:
444 case OPC_STLW:
445 case OPC_SPILL_MACRO:
446 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
447 validate_reg_size(ctx, instr->srcs[1], instr->cat6.type);
448 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
449 break;
450 case OPC_STIB:
451 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
452 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
453 validate_reg_size(ctx, instr->srcs[3], instr->cat6.type);
454 break;
455 case OPC_GETFIBERID:
456 case OPC_GETSPID:
457 case OPC_GETWID:
458 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
459 break;
460 case OPC_STC:
461 case OPC_STSC:
462 validate_reg_size(ctx, instr->srcs[0], instr->cat6.type);
463 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
464 break;
465 case OPC_PUSH_CONSTS_LOAD_MACRO:
466 break;
467 case OPC_LDC:
468 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
469 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
470 validate_assert(ctx, !!(instr->dsts[0]->flags & IR3_REG_SHARED) ==
471 !!(instr->flags & IR3_INSTR_U));
472 break;
473 case OPC_LDC_K:
474 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
475 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
476 break;
477 case OPC_LDP:
478 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
479 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
480 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
481 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
482 break;
483 case OPC_ATOMIC_B_CMPXCHG:
484 if (instr->cat6.type == TYPE_ATOMIC_U64) {
485 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
486 validate_assert(ctx, instr->dsts[0]->wrmask == 0x3f);
487 } else {
488 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
489 }
490 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
491 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
492 break;
493 case OPC_ATOMIC_B_XCHG:
494 if (instr->cat6.type == TYPE_ATOMIC_U64) {
495 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
496 validate_assert(ctx, instr->dsts[0]->wrmask == 0xf);
497 } else {
498 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
499 }
500 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
501 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
502 break;
503 case OPC_ATOMIC_G_CMPXCHG:
504 case OPC_ATOMIC_G_XCHG:
505 if (instr->cat6.type == TYPE_ATOMIC_U64) {
506 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
507 validate_assert(ctx, instr->dsts[0]->wrmask == 0x3);
508 } else {
509 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
510 }
511 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
512 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
513 break;
514 case OPC_SHFL:
515 validate_reg_size(ctx, instr->srcs[0], instr->cat6.type);
516 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
517 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
518 break;
519 case OPC_RAY_INTERSECTION:
520 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
521 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
522 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
523 validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
524 validate_assert(ctx, !(instr->srcs[4]->flags & IR3_REG_HALF));
525 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
526 break;
527 default:
528 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
529 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
530 if (instr->srcs_count > 1)
531 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
532 break;
533 }
534 break;
535 case 7:
536 switch (instr->opc) {
537 case OPC_ALIAS:
538 switch (instr->cat7.alias_scope) {
539 case ALIAS_RT:
540 validate_assert(ctx, instr->dsts[0]->flags & IR3_REG_RT);
541 validate_assert(ctx, instr->cat7.alias_table_size_minus_one == 0);
542 break;
543 case ALIAS_TEX:
544 validate_assert(ctx, instr->cat7.alias_table_size_minus_one < 16);
545 break;
546 case ALIAS_MEM:
547 break;
548 }
549 break;
550 default:
551 break;
552 }
553 }
554
555 if (instr->opc == OPC_META_PARALLEL_COPY) {
556 foreach_src_n (src, n, instr) {
557 validate_assert(ctx, (src->flags & IR3_REG_HALF) ==
558 (instr->dsts[n]->flags & IR3_REG_HALF));
559 if (instr->dsts[n]->flags & IR3_REG_SHARED) {
560 validate_assert(ctx, src->flags & (IR3_REG_SHARED | IR3_REG_CONST |
561 IR3_REG_IMMED));
562 } else {
563 validate_assert(ctx, !(src->flags & IR3_REG_SHARED));
564 }
565 }
566 }
567 }
568
569 static bool
is_physical_successor(struct ir3_block * block,struct ir3_block * succ)570 is_physical_successor(struct ir3_block *block, struct ir3_block *succ)
571 {
572 for (unsigned i = 0; i < block->physical_successors_count; i++)
573 if (block->physical_successors[i] == succ)
574 return true;
575 return false;
576 }
577
578 void
ir3_validate(struct ir3 * ir)579 ir3_validate(struct ir3 *ir)
580 {
581 #ifdef NDEBUG
582 #define VALIDATE 0
583 #else
584 #define VALIDATE 1
585 #endif
586
587 if (!VALIDATE)
588 return;
589
590 struct ir3_validate_ctx *ctx = ralloc_size(NULL, sizeof(*ctx));
591
592 ctx->ir = ir;
593 ctx->defs = _mesa_pointer_set_create(ctx);
594
595 foreach_block (block, &ir->block_list) {
596 ctx->current_block = block;
597 ctx->current_instr = NULL;
598
599 /* We require that the first block does not have any predecessors,
600 * which allows us to assume that phi nodes and meta:input's do not
601 * appear in the same basic block.
602 */
603 validate_assert(
604 ctx, block != ir3_start_block(ir) || block->predecessors_count == 0);
605
606 struct ir3_instruction *prev = NULL;
607 foreach_instr (instr, &block->instr_list) {
608 ctx->current_instr = instr;
609 validate_assert(ctx, instr->block == block);
610 if (instr->opc == OPC_META_PHI) {
611 /* phis must be the first in the block */
612 validate_assert(ctx, prev == NULL || prev->opc == OPC_META_PHI);
613 validate_phi(ctx, instr);
614 } else {
615 validate_instr(ctx, instr);
616 }
617 prev = instr;
618 }
619
620 for (unsigned i = 0; i < 2; i++) {
621 if (block->successors[i]) {
622 validate_phi_src(ctx, block->successors[i], block);
623
624 ctx->current_instr = NULL;
625
626 /* Each logical successor should also be a physical successor: */
627 if (block->physical_successors_count > 0)
628 validate_assert(ctx, is_physical_successor(block, block->successors[i]));
629 }
630 }
631
632 validate_assert(ctx, block->successors[0] || !block->successors[1]);
633 }
634
635 ralloc_free(ctx);
636 }
637