1/*
2 * Copyright © 2020 Google, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include <stdlib.h>
25
26#include "util/ralloc.h"
27
28#include "ir3.h"
29
30struct ir3_validate_ctx {
31   struct ir3 *ir;
32
33   /* Current block being validated: */
34   struct ir3_block *current_block;
35
36   /* Current instruction being validated: */
37   struct ir3_instruction *current_instr;
38
39   /* Set of instructions found so far, used to validate that we
40    * don't have SSA uses that occure before def's
41    */
42   struct set *defs;
43};
44
45static void
46validate_error(struct ir3_validate_ctx *ctx, const char *condstr)
47{
48   fprintf(stderr, "validation fail: %s\n", condstr);
49   if (ctx->current_instr) {
50      fprintf(stderr, "  -> for instruction: ");
51      ir3_print_instr(ctx->current_instr);
52   } else {
53      fprintf(stderr, "  -> for block%u\n", block_id(ctx->current_block));
54   }
55   abort();
56}
57
58#define validate_assert(ctx, cond)                                             \
59   do {                                                                        \
60      if (!(cond)) {                                                           \
61         validate_error(ctx, #cond);                                           \
62      }                                                                        \
63   } while (0)
64
65static unsigned
66reg_class_flags(struct ir3_register *reg)
67{
68   return reg->flags & (IR3_REG_HALF | IR3_REG_SHARED);
69}
70
71static void
72validate_src(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr,
73             struct ir3_register *reg)
74{
75   if (reg->flags & IR3_REG_IMMED)
76      validate_assert(ctx, ir3_valid_immediate(instr, reg->iim_val));
77
78   if (!(reg->flags & IR3_REG_SSA) || !reg->def)
79      return;
80
81   struct ir3_register *src = reg->def;
82
83   validate_assert(ctx, _mesa_set_search(ctx->defs, src->instr));
84   validate_assert(ctx, src->wrmask == reg->wrmask);
85   validate_assert(ctx, reg_class_flags(src) == reg_class_flags(reg));
86
87   if (reg->tied) {
88      validate_assert(ctx, reg->tied->tied == reg);
89      bool found = false;
90      foreach_dst (dst, instr) {
91         if (dst == reg->tied) {
92            found = true;
93            break;
94         }
95      }
96      validate_assert(ctx,
97                      found && "tied register not in the same instruction");
98   }
99}
100
101/* phi sources are logically read at the end of the predecessor basic block,
102 * and we have to validate them then in order to correctly validate that the
103 * use comes after the definition for loop phis.
104 */
105static void
106validate_phi_src(struct ir3_validate_ctx *ctx, struct ir3_block *block,
107                 struct ir3_block *pred)
108{
109   unsigned pred_idx = ir3_block_get_pred_index(block, pred);
110
111   foreach_instr (phi, &block->instr_list) {
112      if (phi->opc != OPC_META_PHI)
113         break;
114
115      ctx->current_instr = phi;
116      validate_assert(ctx, phi->srcs_count == block->predecessors_count);
117      validate_src(ctx, phi, phi->srcs[pred_idx]);
118   }
119}
120
121static void
122validate_phi(struct ir3_validate_ctx *ctx, struct ir3_instruction *phi)
123{
124   _mesa_set_add(ctx->defs, phi);
125   validate_assert(ctx, phi->dsts_count == 1);
126   validate_assert(ctx, is_dest_gpr(phi->dsts[0]));
127}
128
129static void
130validate_dst(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr,
131             struct ir3_register *reg)
132{
133   if (reg->tied) {
134      validate_assert(ctx, reg->tied->tied == reg);
135      validate_assert(ctx, reg_class_flags(reg->tied) == reg_class_flags(reg));
136      validate_assert(ctx, reg->tied->wrmask == reg->wrmask);
137      if (reg->flags & IR3_REG_ARRAY) {
138         validate_assert(ctx, reg->tied->array.base == reg->array.base);
139         validate_assert(ctx, reg->tied->size == reg->size);
140      }
141      bool found = false;
142      foreach_src (src, instr) {
143         if (src == reg->tied) {
144            found = true;
145            break;
146         }
147      }
148      validate_assert(ctx,
149                      found && "tied register not in the same instruction");
150   }
151
152   if (reg->flags & IR3_REG_SSA)
153      validate_assert(ctx, reg->instr == instr);
154
155   if (reg->flags & IR3_REG_RELATIV)
156      validate_assert(ctx, instr->address);
157}
158
159#define validate_reg_size(ctx, reg, type)                                      \
160   validate_assert(                                                            \
161      ctx, (type_size(type) <= 16) == !!((reg)->flags & IR3_REG_HALF))
162
163static void
164validate_instr(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr)
165{
166   struct ir3_register *last_reg = NULL;
167
168   foreach_src_n (reg, n, instr) {
169      if (reg->flags & IR3_REG_RELATIV)
170         validate_assert(ctx, instr->address);
171
172      validate_src(ctx, instr, reg);
173
174      /* Validate that all src's are either half of full.
175       *
176       * Note: tex instructions w/ .s2en are a bit special in that the
177       * tex/samp src reg is half-reg for non-bindless and full for
178       * bindless, irrespective of the precision of other srcs. The
179       * tex/samp src is the first src reg when .s2en is set
180       */
181      if (reg->tied) {
182         /* must have the same size as the destination, handled in
183          * validate_reg().
184          */
185      } else if (reg == instr->address) {
186         validate_assert(ctx, reg->flags & IR3_REG_HALF);
187      } else if ((instr->flags & IR3_INSTR_S2EN) && (n < 2)) {
188         if (n == 0) {
189            if (instr->flags & IR3_INSTR_B)
190               validate_assert(ctx, !(reg->flags & IR3_REG_HALF));
191            else
192               validate_assert(ctx, reg->flags & IR3_REG_HALF);
193         }
194      } else if (opc_cat(instr->opc) == 1 || opc_cat(instr->opc) == 6) {
195         /* handled below */
196      } else if (opc_cat(instr->opc) == 0) {
197         /* end/chmask/etc are allowed to have different size sources */
198      } else if (instr->opc == OPC_META_PARALLEL_COPY) {
199         /* pcopy sources have to match with their destination but can have
200          * different sizes from each other.
201          */
202      } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO ||
203                 instr->opc == OPC_READ_FIRST_MACRO ||
204                 instr->opc == OPC_READ_COND_MACRO) {
205         /* nothing yet */
206      } else if (n > 0) {
207         validate_assert(ctx, (last_reg->flags & IR3_REG_HALF) ==
208                                 (reg->flags & IR3_REG_HALF));
209      }
210
211      last_reg = reg;
212   }
213
214   for (unsigned i = 0; i < instr->dsts_count; i++) {
215      struct ir3_register *reg = instr->dsts[i];
216
217      validate_dst(ctx, instr, reg);
218   }
219
220   _mesa_set_add(ctx->defs, instr);
221
222   /* Check that src/dst types match the register types, and for
223    * instructions that have different opcodes depending on type,
224    * that the opcodes are correct.
225    */
226   switch (opc_cat(instr->opc)) {
227   case 1: /* move instructions */
228      if (instr->opc == OPC_MOVMSK || instr->opc == OPC_BALLOT_MACRO) {
229         validate_assert(ctx, instr->dsts_count == 1);
230         validate_assert(ctx, instr->dsts[0]->flags & IR3_REG_SHARED);
231         validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
232         validate_assert(
233            ctx, util_is_power_of_two_or_zero(instr->dsts[0]->wrmask + 1));
234      } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO ||
235                 instr->opc == OPC_READ_FIRST_MACRO ||
236                 instr->opc == OPC_READ_COND_MACRO) {
237         /* nothing yet */
238      } else if (instr->opc == OPC_ELECT_MACRO || instr->opc == OPC_SHPS_MACRO) {
239         validate_assert(ctx, instr->dsts_count == 1);
240         validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_SHARED));
241      } else if (instr->opc == OPC_SCAN_MACRO) {
242         validate_assert(ctx, instr->dsts_count == 3);
243         validate_assert(ctx, instr->srcs_count == 2);
244         validate_assert(ctx, reg_class_flags(instr->dsts[0]) ==
245                              reg_class_flags(instr->srcs[0]));
246         validate_assert(ctx, reg_class_flags(instr->dsts[1]) ==
247                              reg_class_flags(instr->srcs[0]));
248         validate_assert(ctx, reg_class_flags(instr->dsts[2]) == IR3_REG_SHARED);
249      } else {
250         foreach_dst (dst, instr)
251            validate_reg_size(ctx, dst, instr->cat1.dst_type);
252         foreach_src (src, instr) {
253            if (!src->tied && src != instr->address)
254               validate_reg_size(ctx, src, instr->cat1.src_type);
255         }
256
257         switch (instr->opc) {
258         case OPC_SWZ:
259            validate_assert(ctx, instr->srcs_count == 2);
260            validate_assert(ctx, instr->dsts_count == 2);
261            break;
262         case OPC_GAT:
263            validate_assert(ctx, instr->srcs_count == 4);
264            validate_assert(ctx, instr->dsts_count == 1);
265            break;
266         case OPC_SCT:
267            validate_assert(ctx, instr->srcs_count == 1);
268            validate_assert(ctx, instr->dsts_count == 4);
269            break;
270         default:
271            break;
272         }
273      }
274
275      if (instr->opc != OPC_MOV)
276         validate_assert(ctx, !instr->address);
277
278      break;
279   case 3:
280      /* Validate that cat3 opc matches the src type.  We've already checked
281       * that all the src regs are same type
282       */
283      if (instr->srcs[0]->flags & IR3_REG_HALF) {
284         validate_assert(ctx, instr->opc == cat3_half_opc(instr->opc));
285      } else {
286         validate_assert(ctx, instr->opc == cat3_full_opc(instr->opc));
287      }
288      break;
289   case 4:
290      /* Validate that cat4 opc matches the dst type: */
291      if (instr->dsts[0]->flags & IR3_REG_HALF) {
292         validate_assert(ctx, instr->opc == cat4_half_opc(instr->opc));
293      } else {
294         validate_assert(ctx, instr->opc == cat4_full_opc(instr->opc));
295      }
296      break;
297   case 5:
298      validate_reg_size(ctx, instr->dsts[0], instr->cat5.type);
299      break;
300   case 6:
301      switch (instr->opc) {
302      case OPC_RESINFO:
303      case OPC_RESFMT:
304         validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
305         validate_reg_size(ctx, instr->srcs[0], instr->cat6.type);
306         break;
307      case OPC_L2G:
308      case OPC_G2L:
309         validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
310         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
311         break;
312      case OPC_STG:
313         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
314         validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
315         validate_reg_size(ctx, instr->srcs[2], instr->cat6.type);
316         validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
317         break;
318      case OPC_STG_A:
319         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
320         validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
321         validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
322         validate_reg_size(ctx, instr->srcs[4], instr->cat6.type);
323         validate_assert(ctx, !(instr->srcs[5]->flags & IR3_REG_HALF));
324         break;
325      case OPC_STL:
326      case OPC_STP:
327      case OPC_STLW:
328      case OPC_SPILL_MACRO:
329         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
330         validate_reg_size(ctx, instr->srcs[1], instr->cat6.type);
331         validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
332         break;
333      case OPC_STIB:
334         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
335         validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
336         validate_reg_size(ctx, instr->srcs[2], instr->cat6.type);
337         break;
338      case OPC_GETFIBERID:
339      case OPC_GETSPID:
340      case OPC_GETWID:
341         validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
342         break;
343      case OPC_STC:
344         validate_reg_size(ctx, instr->srcs[0], instr->cat6.type);
345         validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
346         break;
347      case OPC_LDC_K:
348         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
349         validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
350         break;
351      default:
352         validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
353         validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
354         if (instr->srcs_count > 1)
355            validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
356         break;
357      }
358   }
359
360   if (instr->opc == OPC_META_PARALLEL_COPY) {
361      foreach_src_n (src, n, instr) {
362         validate_assert(ctx, reg_class_flags(src) ==
363                         reg_class_flags(instr->dsts[n]));
364      }
365   }
366}
367
368static bool
369is_physical_successor(struct ir3_block *block, struct ir3_block *succ)
370{
371   for (unsigned i = 0; i < ARRAY_SIZE(block->physical_successors); i++)
372      if (block->physical_successors[i] == succ)
373         return true;
374   return false;
375}
376
377void
378ir3_validate(struct ir3 *ir)
379{
380#ifdef NDEBUG
381#define VALIDATE 0
382#else
383#define VALIDATE 1
384#endif
385
386   if (!VALIDATE)
387      return;
388
389   struct ir3_validate_ctx *ctx = ralloc_size(NULL, sizeof(*ctx));
390
391   ctx->ir = ir;
392   ctx->defs = _mesa_pointer_set_create(ctx);
393
394   foreach_block (block, &ir->block_list) {
395      ctx->current_block = block;
396      ctx->current_instr = NULL;
397
398      /* We require that the first block does not have any predecessors,
399       * which allows us to assume that phi nodes and meta:input's do not
400       * appear in the same basic block.
401       */
402      validate_assert(
403         ctx, block != ir3_start_block(ir) || block->predecessors_count == 0);
404
405      struct ir3_instruction *prev = NULL;
406      foreach_instr (instr, &block->instr_list) {
407         ctx->current_instr = instr;
408         if (instr->opc == OPC_META_PHI) {
409            /* phis must be the first in the block */
410            validate_assert(ctx, prev == NULL || prev->opc == OPC_META_PHI);
411            validate_phi(ctx, instr);
412         } else {
413            validate_instr(ctx, instr);
414         }
415         prev = instr;
416      }
417
418      for (unsigned i = 0; i < 2; i++) {
419         if (block->successors[i]) {
420            validate_phi_src(ctx, block->successors[i], block);
421
422            ctx->current_instr = NULL;
423
424            /* Each logical successor should also be a physical successor: */
425            validate_assert(ctx, is_physical_successor(block, block->successors[i]));
426         }
427      }
428
429      validate_assert(ctx, block->successors[0] || !block->successors[1]);
430      validate_assert(ctx, block->physical_successors[0] || !block->physical_successors[1]);
431   }
432
433   ralloc_free(ctx);
434}
435