• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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