1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2014 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Connor Abbott (cwabbott0@gmail.com)
25b8e80941Smrg *
26b8e80941Smrg */
27b8e80941Smrg
28b8e80941Smrg#include "nir.h"
29b8e80941Smrg#include "c11/threads.h"
30b8e80941Smrg#include <assert.h>
31b8e80941Smrg
32b8e80941Smrg/*
33b8e80941Smrg * This file checks for invalid IR indicating a bug somewhere in the compiler.
34b8e80941Smrg */
35b8e80941Smrg
36b8e80941Smrg/* Since this file is just a pile of asserts, don't bother compiling it if
37b8e80941Smrg * we're not building a debug build.
38b8e80941Smrg */
39b8e80941Smrg#ifndef NDEBUG
40b8e80941Smrg
41b8e80941Smrg/*
42b8e80941Smrg * Per-register validation state.
43b8e80941Smrg */
44b8e80941Smrg
45b8e80941Smrgtypedef struct {
46b8e80941Smrg   /*
47b8e80941Smrg    * equivalent to the uses and defs in nir_register, but built up by the
48b8e80941Smrg    * validator. At the end, we verify that the sets have the same entries.
49b8e80941Smrg    */
50b8e80941Smrg   struct set *uses, *if_uses, *defs;
51b8e80941Smrg   nir_function_impl *where_defined; /* NULL for global registers */
52b8e80941Smrg} reg_validate_state;
53b8e80941Smrg
54b8e80941Smrgtypedef struct {
55b8e80941Smrg   /*
56b8e80941Smrg    * equivalent to the uses in nir_ssa_def, but built up by the validator.
57b8e80941Smrg    * At the end, we verify that the sets have the same entries.
58b8e80941Smrg    */
59b8e80941Smrg   struct set *uses, *if_uses;
60b8e80941Smrg   nir_function_impl *where_defined;
61b8e80941Smrg} ssa_def_validate_state;
62b8e80941Smrg
63b8e80941Smrgtypedef struct {
64b8e80941Smrg   /* map of register -> validation state (struct above) */
65b8e80941Smrg   struct hash_table *regs;
66b8e80941Smrg
67b8e80941Smrg   /* the current shader being validated */
68b8e80941Smrg   nir_shader *shader;
69b8e80941Smrg
70b8e80941Smrg   /* the current instruction being validated */
71b8e80941Smrg   nir_instr *instr;
72b8e80941Smrg
73b8e80941Smrg   /* the current variable being validated */
74b8e80941Smrg   nir_variable *var;
75b8e80941Smrg
76b8e80941Smrg   /* the current basic block being validated */
77b8e80941Smrg   nir_block *block;
78b8e80941Smrg
79b8e80941Smrg   /* the current if statement being validated */
80b8e80941Smrg   nir_if *if_stmt;
81b8e80941Smrg
82b8e80941Smrg   /* the current loop being visited */
83b8e80941Smrg   nir_loop *loop;
84b8e80941Smrg
85b8e80941Smrg   /* the parent of the current cf node being visited */
86b8e80941Smrg   nir_cf_node *parent_node;
87b8e80941Smrg
88b8e80941Smrg   /* the current function implementation being validated */
89b8e80941Smrg   nir_function_impl *impl;
90b8e80941Smrg
91b8e80941Smrg   /* map of SSA value -> function implementation where it is defined */
92b8e80941Smrg   struct hash_table *ssa_defs;
93b8e80941Smrg
94b8e80941Smrg   /* bitset of ssa definitions we have found; used to check uniqueness */
95b8e80941Smrg   BITSET_WORD *ssa_defs_found;
96b8e80941Smrg
97b8e80941Smrg   /* bitset of registers we have currently found; used to check uniqueness */
98b8e80941Smrg   BITSET_WORD *regs_found;
99b8e80941Smrg
100b8e80941Smrg   /* map of variable -> function implementation where it is defined or NULL
101b8e80941Smrg    * if it is a global variable
102b8e80941Smrg    */
103b8e80941Smrg   struct hash_table *var_defs;
104b8e80941Smrg
105b8e80941Smrg   /* map of instruction/var/etc to failed assert string */
106b8e80941Smrg   struct hash_table *errors;
107b8e80941Smrg} validate_state;
108b8e80941Smrg
109b8e80941Smrgstatic void
110b8e80941Smrglog_error(validate_state *state, const char *cond, const char *file, int line)
111b8e80941Smrg{
112b8e80941Smrg   const void *obj;
113b8e80941Smrg
114b8e80941Smrg   if (state->instr)
115b8e80941Smrg      obj = state->instr;
116b8e80941Smrg   else if (state->var)
117b8e80941Smrg      obj = state->var;
118b8e80941Smrg   else
119b8e80941Smrg      obj = cond;
120b8e80941Smrg
121b8e80941Smrg   char *msg = ralloc_asprintf(state->errors, "error: %s (%s:%d)",
122b8e80941Smrg                               cond, file, line);
123b8e80941Smrg
124b8e80941Smrg   _mesa_hash_table_insert(state->errors, obj, msg);
125b8e80941Smrg}
126b8e80941Smrg
127b8e80941Smrg#define validate_assert(state, cond) do {             \
128b8e80941Smrg      if (!(cond))                                    \
129b8e80941Smrg         log_error(state, #cond, __FILE__, __LINE__); \
130b8e80941Smrg   } while (0)
131b8e80941Smrg
132b8e80941Smrgstatic void validate_src(nir_src *src, validate_state *state,
133b8e80941Smrg                         unsigned bit_sizes, unsigned num_components);
134b8e80941Smrg
135b8e80941Smrgstatic void
136b8e80941Smrgvalidate_reg_src(nir_src *src, validate_state *state,
137b8e80941Smrg                 unsigned bit_sizes, unsigned num_components)
138b8e80941Smrg{
139b8e80941Smrg   validate_assert(state, src->reg.reg != NULL);
140b8e80941Smrg
141b8e80941Smrg   struct hash_entry *entry;
142b8e80941Smrg   entry = _mesa_hash_table_search(state->regs, src->reg.reg);
143b8e80941Smrg   validate_assert(state, entry);
144b8e80941Smrg
145b8e80941Smrg   reg_validate_state *reg_state = (reg_validate_state *) entry->data;
146b8e80941Smrg
147b8e80941Smrg   if (state->instr) {
148b8e80941Smrg      _mesa_set_add(reg_state->uses, src);
149b8e80941Smrg   } else {
150b8e80941Smrg      validate_assert(state, state->if_stmt);
151b8e80941Smrg      _mesa_set_add(reg_state->if_uses, src);
152b8e80941Smrg   }
153b8e80941Smrg
154b8e80941Smrg   validate_assert(state, reg_state->where_defined == state->impl &&
155b8e80941Smrg          "using a register declared in a different function");
156b8e80941Smrg
157b8e80941Smrg   if (bit_sizes)
158b8e80941Smrg      validate_assert(state, src->reg.reg->bit_size & bit_sizes);
159b8e80941Smrg   if (num_components)
160b8e80941Smrg      validate_assert(state, src->reg.reg->num_components == num_components);
161b8e80941Smrg
162b8e80941Smrg   validate_assert(state, (src->reg.reg->num_array_elems == 0 ||
163b8e80941Smrg          src->reg.base_offset < src->reg.reg->num_array_elems) &&
164b8e80941Smrg          "definitely out-of-bounds array access");
165b8e80941Smrg
166b8e80941Smrg   if (src->reg.indirect) {
167b8e80941Smrg      validate_assert(state, src->reg.reg->num_array_elems != 0);
168b8e80941Smrg      validate_assert(state, (src->reg.indirect->is_ssa ||
169b8e80941Smrg              src->reg.indirect->reg.indirect == NULL) &&
170b8e80941Smrg             "only one level of indirection allowed");
171b8e80941Smrg      validate_src(src->reg.indirect, state, 32, 1);
172b8e80941Smrg   }
173b8e80941Smrg}
174b8e80941Smrg
175b8e80941Smrgstatic void
176b8e80941Smrgvalidate_ssa_src(nir_src *src, validate_state *state,
177b8e80941Smrg                 unsigned bit_sizes, unsigned num_components)
178b8e80941Smrg{
179b8e80941Smrg   validate_assert(state, src->ssa != NULL);
180b8e80941Smrg
181b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs, src->ssa);
182b8e80941Smrg
183b8e80941Smrg   validate_assert(state, entry);
184b8e80941Smrg
185b8e80941Smrg   if (!entry)
186b8e80941Smrg      return;
187b8e80941Smrg
188b8e80941Smrg   ssa_def_validate_state *def_state = (ssa_def_validate_state *)entry->data;
189b8e80941Smrg
190b8e80941Smrg   validate_assert(state, def_state->where_defined == state->impl &&
191b8e80941Smrg          "using an SSA value defined in a different function");
192b8e80941Smrg
193b8e80941Smrg   if (state->instr) {
194b8e80941Smrg      _mesa_set_add(def_state->uses, src);
195b8e80941Smrg   } else {
196b8e80941Smrg      validate_assert(state, state->if_stmt);
197b8e80941Smrg      _mesa_set_add(def_state->if_uses, src);
198b8e80941Smrg   }
199b8e80941Smrg
200b8e80941Smrg   if (bit_sizes)
201b8e80941Smrg      validate_assert(state, src->ssa->bit_size & bit_sizes);
202b8e80941Smrg   if (num_components)
203b8e80941Smrg      validate_assert(state, src->ssa->num_components == num_components);
204b8e80941Smrg
205b8e80941Smrg   /* TODO validate that the use is dominated by the definition */
206b8e80941Smrg}
207b8e80941Smrg
208b8e80941Smrgstatic void
209b8e80941Smrgvalidate_src(nir_src *src, validate_state *state,
210b8e80941Smrg             unsigned bit_sizes, unsigned num_components)
211b8e80941Smrg{
212b8e80941Smrg   if (state->instr)
213b8e80941Smrg      validate_assert(state, src->parent_instr == state->instr);
214b8e80941Smrg   else
215b8e80941Smrg      validate_assert(state, src->parent_if == state->if_stmt);
216b8e80941Smrg
217b8e80941Smrg   if (src->is_ssa)
218b8e80941Smrg      validate_ssa_src(src, state, bit_sizes, num_components);
219b8e80941Smrg   else
220b8e80941Smrg      validate_reg_src(src, state, bit_sizes, num_components);
221b8e80941Smrg}
222b8e80941Smrg
223b8e80941Smrgstatic void
224b8e80941Smrgvalidate_alu_src(nir_alu_instr *instr, unsigned index, validate_state *state)
225b8e80941Smrg{
226b8e80941Smrg   nir_alu_src *src = &instr->src[index];
227b8e80941Smrg
228b8e80941Smrg   unsigned num_components = nir_src_num_components(src->src);
229b8e80941Smrg   for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
230b8e80941Smrg      validate_assert(state, src->swizzle[i] < NIR_MAX_VEC_COMPONENTS);
231b8e80941Smrg
232b8e80941Smrg      if (nir_alu_instr_channel_used(instr, index, i))
233b8e80941Smrg         validate_assert(state, src->swizzle[i] < num_components);
234b8e80941Smrg   }
235b8e80941Smrg
236b8e80941Smrg   validate_src(&src->src, state, 0, 0);
237b8e80941Smrg}
238b8e80941Smrg
239b8e80941Smrgstatic void
240b8e80941Smrgvalidate_reg_dest(nir_reg_dest *dest, validate_state *state,
241b8e80941Smrg                  unsigned bit_sizes, unsigned num_components)
242b8e80941Smrg{
243b8e80941Smrg   validate_assert(state, dest->reg != NULL);
244b8e80941Smrg
245b8e80941Smrg   validate_assert(state, dest->parent_instr == state->instr);
246b8e80941Smrg
247b8e80941Smrg   struct hash_entry *entry2;
248b8e80941Smrg   entry2 = _mesa_hash_table_search(state->regs, dest->reg);
249b8e80941Smrg
250b8e80941Smrg   validate_assert(state, entry2);
251b8e80941Smrg
252b8e80941Smrg   reg_validate_state *reg_state = (reg_validate_state *) entry2->data;
253b8e80941Smrg   _mesa_set_add(reg_state->defs, dest);
254b8e80941Smrg
255b8e80941Smrg   validate_assert(state, reg_state->where_defined == state->impl &&
256b8e80941Smrg          "writing to a register declared in a different function");
257b8e80941Smrg
258b8e80941Smrg   if (bit_sizes)
259b8e80941Smrg      validate_assert(state, dest->reg->bit_size & bit_sizes);
260b8e80941Smrg   if (num_components)
261b8e80941Smrg      validate_assert(state, dest->reg->num_components == num_components);
262b8e80941Smrg
263b8e80941Smrg   validate_assert(state, (dest->reg->num_array_elems == 0 ||
264b8e80941Smrg          dest->base_offset < dest->reg->num_array_elems) &&
265b8e80941Smrg          "definitely out-of-bounds array access");
266b8e80941Smrg
267b8e80941Smrg   if (dest->indirect) {
268b8e80941Smrg      validate_assert(state, dest->reg->num_array_elems != 0);
269b8e80941Smrg      validate_assert(state, (dest->indirect->is_ssa || dest->indirect->reg.indirect == NULL) &&
270b8e80941Smrg             "only one level of indirection allowed");
271b8e80941Smrg      validate_src(dest->indirect, state, 32, 1);
272b8e80941Smrg   }
273b8e80941Smrg}
274b8e80941Smrg
275b8e80941Smrgstatic void
276b8e80941Smrgvalidate_ssa_def(nir_ssa_def *def, validate_state *state)
277b8e80941Smrg{
278b8e80941Smrg   validate_assert(state, def->index < state->impl->ssa_alloc);
279b8e80941Smrg   validate_assert(state, !BITSET_TEST(state->ssa_defs_found, def->index));
280b8e80941Smrg   BITSET_SET(state->ssa_defs_found, def->index);
281b8e80941Smrg
282b8e80941Smrg   validate_assert(state, def->parent_instr == state->instr);
283b8e80941Smrg
284b8e80941Smrg   validate_assert(state, (def->num_components <= 4) ||
285b8e80941Smrg                          (def->num_components == 8) ||
286b8e80941Smrg                          (def->num_components == 16));
287b8e80941Smrg
288b8e80941Smrg   list_validate(&def->uses);
289b8e80941Smrg   list_validate(&def->if_uses);
290b8e80941Smrg
291b8e80941Smrg   ssa_def_validate_state *def_state = ralloc(state->ssa_defs,
292b8e80941Smrg                                              ssa_def_validate_state);
293b8e80941Smrg   def_state->where_defined = state->impl;
294b8e80941Smrg   def_state->uses = _mesa_pointer_set_create(def_state);
295b8e80941Smrg   def_state->if_uses = _mesa_pointer_set_create(def_state);
296b8e80941Smrg   _mesa_hash_table_insert(state->ssa_defs, def, def_state);
297b8e80941Smrg}
298b8e80941Smrg
299b8e80941Smrgstatic void
300b8e80941Smrgvalidate_dest(nir_dest *dest, validate_state *state,
301b8e80941Smrg              unsigned bit_sizes, unsigned num_components)
302b8e80941Smrg{
303b8e80941Smrg   if (dest->is_ssa) {
304b8e80941Smrg      if (bit_sizes)
305b8e80941Smrg         validate_assert(state, dest->ssa.bit_size & bit_sizes);
306b8e80941Smrg      if (num_components)
307b8e80941Smrg         validate_assert(state, dest->ssa.num_components == num_components);
308b8e80941Smrg      validate_ssa_def(&dest->ssa, state);
309b8e80941Smrg   } else {
310b8e80941Smrg      validate_reg_dest(&dest->reg, state, bit_sizes, num_components);
311b8e80941Smrg   }
312b8e80941Smrg}
313b8e80941Smrg
314b8e80941Smrgstatic void
315b8e80941Smrgvalidate_alu_dest(nir_alu_instr *instr, validate_state *state)
316b8e80941Smrg{
317b8e80941Smrg   nir_alu_dest *dest = &instr->dest;
318b8e80941Smrg
319b8e80941Smrg   unsigned dest_size = nir_dest_num_components(dest->dest);
320b8e80941Smrg   /*
321b8e80941Smrg    * validate that the instruction doesn't write to components not in the
322b8e80941Smrg    * register/SSA value
323b8e80941Smrg    */
324b8e80941Smrg   validate_assert(state, !(dest->write_mask & ~((1 << dest_size) - 1)));
325b8e80941Smrg
326b8e80941Smrg   /* validate that saturate is only ever used on instructions with
327b8e80941Smrg    * destinations of type float
328b8e80941Smrg    */
329b8e80941Smrg   nir_alu_instr *alu = nir_instr_as_alu(state->instr);
330b8e80941Smrg   validate_assert(state,
331b8e80941Smrg          (nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) ==
332b8e80941Smrg           nir_type_float) ||
333b8e80941Smrg          !dest->saturate);
334b8e80941Smrg
335b8e80941Smrg   validate_dest(&dest->dest, state, 0, 0);
336b8e80941Smrg}
337b8e80941Smrg
338b8e80941Smrgstatic void
339b8e80941Smrgvalidate_alu_instr(nir_alu_instr *instr, validate_state *state)
340b8e80941Smrg{
341b8e80941Smrg   validate_assert(state, instr->op < nir_num_opcodes);
342b8e80941Smrg
343b8e80941Smrg   unsigned instr_bit_size = 0;
344b8e80941Smrg   for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
345b8e80941Smrg      nir_alu_type src_type = nir_op_infos[instr->op].input_types[i];
346b8e80941Smrg      unsigned src_bit_size = nir_src_bit_size(instr->src[i].src);
347b8e80941Smrg      if (nir_alu_type_get_type_size(src_type)) {
348b8e80941Smrg         validate_assert(state, src_bit_size == nir_alu_type_get_type_size(src_type));
349b8e80941Smrg      } else if (instr_bit_size) {
350b8e80941Smrg         validate_assert(state, src_bit_size == instr_bit_size);
351b8e80941Smrg      } else {
352b8e80941Smrg         instr_bit_size = src_bit_size;
353b8e80941Smrg      }
354b8e80941Smrg
355b8e80941Smrg      if (nir_alu_type_get_base_type(src_type) == nir_type_float) {
356b8e80941Smrg         /* 8-bit float isn't a thing */
357b8e80941Smrg         validate_assert(state, src_bit_size == 16 || src_bit_size == 32 ||
358b8e80941Smrg                                src_bit_size == 64);
359b8e80941Smrg      }
360b8e80941Smrg
361b8e80941Smrg      validate_alu_src(instr, i, state);
362b8e80941Smrg   }
363b8e80941Smrg
364b8e80941Smrg   nir_alu_type dest_type = nir_op_infos[instr->op].output_type;
365b8e80941Smrg   unsigned dest_bit_size = nir_dest_bit_size(instr->dest.dest);
366b8e80941Smrg   if (nir_alu_type_get_type_size(dest_type)) {
367b8e80941Smrg      validate_assert(state, dest_bit_size == nir_alu_type_get_type_size(dest_type));
368b8e80941Smrg   } else if (instr_bit_size) {
369b8e80941Smrg      validate_assert(state, dest_bit_size == instr_bit_size);
370b8e80941Smrg   } else {
371b8e80941Smrg      /* The only unsized thing is the destination so it's vacuously valid */
372b8e80941Smrg   }
373b8e80941Smrg
374b8e80941Smrg   if (nir_alu_type_get_base_type(dest_type) == nir_type_float) {
375b8e80941Smrg      /* 8-bit float isn't a thing */
376b8e80941Smrg      validate_assert(state, dest_bit_size == 16 || dest_bit_size == 32 ||
377b8e80941Smrg                             dest_bit_size == 64);
378b8e80941Smrg   }
379b8e80941Smrg
380b8e80941Smrg   validate_alu_dest(instr, state);
381b8e80941Smrg}
382b8e80941Smrg
383b8e80941Smrgstatic void
384b8e80941Smrgvalidate_var_use(nir_variable *var, validate_state *state)
385b8e80941Smrg{
386b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->var_defs, var);
387b8e80941Smrg   validate_assert(state, entry);
388b8e80941Smrg   if (var->data.mode == nir_var_function_temp)
389b8e80941Smrg      validate_assert(state, (nir_function_impl *) entry->data == state->impl);
390b8e80941Smrg}
391b8e80941Smrg
392b8e80941Smrgstatic void
393b8e80941Smrgvalidate_deref_instr(nir_deref_instr *instr, validate_state *state)
394b8e80941Smrg{
395b8e80941Smrg   if (instr->deref_type == nir_deref_type_var) {
396b8e80941Smrg      /* Variable dereferences are stupid simple. */
397b8e80941Smrg      validate_assert(state, instr->mode == instr->var->data.mode);
398b8e80941Smrg      validate_assert(state, instr->type == instr->var->type);
399b8e80941Smrg      validate_var_use(instr->var, state);
400b8e80941Smrg   } else if (instr->deref_type == nir_deref_type_cast) {
401b8e80941Smrg      /* For cast, we simply have to trust the instruction.  It's up to
402b8e80941Smrg       * lowering passes and front/back-ends to make them sane.
403b8e80941Smrg       */
404b8e80941Smrg      validate_src(&instr->parent, state, 0, 0);
405b8e80941Smrg
406b8e80941Smrg      /* We just validate that the type and mode are there */
407b8e80941Smrg      validate_assert(state, instr->mode);
408b8e80941Smrg      validate_assert(state, instr->type);
409b8e80941Smrg   } else {
410b8e80941Smrg      /* We require the parent to be SSA.  This may be lifted in the future */
411b8e80941Smrg      validate_assert(state, instr->parent.is_ssa);
412b8e80941Smrg
413b8e80941Smrg      /* The parent pointer value must have the same number of components
414b8e80941Smrg       * as the destination.
415b8e80941Smrg       */
416b8e80941Smrg      validate_src(&instr->parent, state, nir_dest_bit_size(instr->dest),
417b8e80941Smrg                   nir_dest_num_components(instr->dest));
418b8e80941Smrg
419b8e80941Smrg      nir_instr *parent_instr = instr->parent.ssa->parent_instr;
420b8e80941Smrg
421b8e80941Smrg      /* The parent must come from another deref instruction */
422b8e80941Smrg      validate_assert(state, parent_instr->type == nir_instr_type_deref);
423b8e80941Smrg
424b8e80941Smrg      nir_deref_instr *parent = nir_instr_as_deref(parent_instr);
425b8e80941Smrg
426b8e80941Smrg      validate_assert(state, instr->mode == parent->mode);
427b8e80941Smrg
428b8e80941Smrg      switch (instr->deref_type) {
429b8e80941Smrg      case nir_deref_type_struct:
430b8e80941Smrg         validate_assert(state, glsl_type_is_struct_or_ifc(parent->type));
431b8e80941Smrg         validate_assert(state,
432b8e80941Smrg            instr->strct.index < glsl_get_length(parent->type));
433b8e80941Smrg         validate_assert(state, instr->type ==
434b8e80941Smrg            glsl_get_struct_field(parent->type, instr->strct.index));
435b8e80941Smrg         break;
436b8e80941Smrg
437b8e80941Smrg      case nir_deref_type_array:
438b8e80941Smrg      case nir_deref_type_array_wildcard:
439b8e80941Smrg         if (instr->mode == nir_var_mem_ubo ||
440b8e80941Smrg             instr->mode == nir_var_mem_ssbo ||
441b8e80941Smrg             instr->mode == nir_var_mem_shared ||
442b8e80941Smrg             instr->mode == nir_var_mem_global) {
443b8e80941Smrg            /* Shared variables and UBO/SSBOs have a bit more relaxed rules
444b8e80941Smrg             * because we need to be able to handle array derefs on vectors.
445b8e80941Smrg             * Fortunately, nir_lower_io handles these just fine.
446b8e80941Smrg             */
447b8e80941Smrg            validate_assert(state, glsl_type_is_array(parent->type) ||
448b8e80941Smrg                                   glsl_type_is_matrix(parent->type) ||
449b8e80941Smrg                                   glsl_type_is_vector(parent->type));
450b8e80941Smrg         } else {
451b8e80941Smrg            /* Most of NIR cannot handle array derefs on vectors */
452b8e80941Smrg            validate_assert(state, glsl_type_is_array(parent->type) ||
453b8e80941Smrg                                   glsl_type_is_matrix(parent->type));
454b8e80941Smrg         }
455b8e80941Smrg         validate_assert(state,
456b8e80941Smrg            instr->type == glsl_get_array_element(parent->type));
457b8e80941Smrg
458b8e80941Smrg         if (instr->deref_type == nir_deref_type_array) {
459b8e80941Smrg            validate_src(&instr->arr.index, state,
460b8e80941Smrg                         nir_dest_bit_size(instr->dest), 1);
461b8e80941Smrg         }
462b8e80941Smrg         break;
463b8e80941Smrg
464b8e80941Smrg      case nir_deref_type_ptr_as_array:
465b8e80941Smrg         /* ptr_as_array derefs must have a parent that is either an array,
466b8e80941Smrg          * ptr_as_array, or cast.  If the parent is a cast, we get the stride
467b8e80941Smrg          * information (if any) from the cast deref.
468b8e80941Smrg          */
469b8e80941Smrg         validate_assert(state,
470b8e80941Smrg                         parent->deref_type == nir_deref_type_array ||
471b8e80941Smrg                         parent->deref_type == nir_deref_type_ptr_as_array ||
472b8e80941Smrg                         parent->deref_type == nir_deref_type_cast);
473b8e80941Smrg         validate_src(&instr->arr.index, state,
474b8e80941Smrg                      nir_dest_bit_size(instr->dest), 1);
475b8e80941Smrg         break;
476b8e80941Smrg
477b8e80941Smrg      default:
478b8e80941Smrg         unreachable("Invalid deref instruction type");
479b8e80941Smrg      }
480b8e80941Smrg   }
481b8e80941Smrg
482b8e80941Smrg   /* We intentionally don't validate the size of the destination because we
483b8e80941Smrg    * want to let other compiler components such as SPIR-V decide how big
484b8e80941Smrg    * pointers should be.
485b8e80941Smrg    */
486b8e80941Smrg   validate_dest(&instr->dest, state, 0, 0);
487b8e80941Smrg
488b8e80941Smrg   /* Deref instructions as if conditions don't make sense because if
489b8e80941Smrg    * conditions expect well-formed Booleans.  If you want to compare with
490b8e80941Smrg    * NULL, an explicit comparison operation should be used.
491b8e80941Smrg    */
492b8e80941Smrg   validate_assert(state, list_empty(&instr->dest.ssa.if_uses));
493b8e80941Smrg}
494b8e80941Smrg
495b8e80941Smrgstatic void
496b8e80941Smrgvalidate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
497b8e80941Smrg{
498b8e80941Smrg   unsigned dest_bit_size = 0;
499b8e80941Smrg   unsigned src_bit_sizes[NIR_INTRINSIC_MAX_INPUTS] = { 0, };
500b8e80941Smrg   switch (instr->intrinsic) {
501b8e80941Smrg   case nir_intrinsic_load_param: {
502b8e80941Smrg      unsigned param_idx = nir_intrinsic_param_idx(instr);
503b8e80941Smrg      validate_assert(state, param_idx < state->impl->function->num_params);
504b8e80941Smrg      nir_parameter *param = &state->impl->function->params[param_idx];
505b8e80941Smrg      validate_assert(state, instr->num_components == param->num_components);
506b8e80941Smrg      dest_bit_size = param->bit_size;
507b8e80941Smrg      break;
508b8e80941Smrg   }
509b8e80941Smrg
510b8e80941Smrg   case nir_intrinsic_load_deref: {
511b8e80941Smrg      nir_deref_instr *src = nir_src_as_deref(instr->src[0]);
512b8e80941Smrg      validate_assert(state, glsl_type_is_vector_or_scalar(src->type) ||
513b8e80941Smrg                      (src->mode == nir_var_uniform &&
514b8e80941Smrg                       glsl_get_base_type(src->type) == GLSL_TYPE_SUBROUTINE));
515b8e80941Smrg      validate_assert(state, instr->num_components ==
516b8e80941Smrg                             glsl_get_vector_elements(src->type));
517b8e80941Smrg      dest_bit_size = glsl_get_bit_size(src->type);
518b8e80941Smrg      /* Also allow 32-bit boolean load operations */
519b8e80941Smrg      if (glsl_type_is_boolean(src->type))
520b8e80941Smrg         dest_bit_size |= 32;
521b8e80941Smrg      break;
522b8e80941Smrg   }
523b8e80941Smrg
524b8e80941Smrg   case nir_intrinsic_store_deref: {
525b8e80941Smrg      nir_deref_instr *dst = nir_src_as_deref(instr->src[0]);
526b8e80941Smrg      validate_assert(state, glsl_type_is_vector_or_scalar(dst->type));
527b8e80941Smrg      validate_assert(state, instr->num_components ==
528b8e80941Smrg                             glsl_get_vector_elements(dst->type));
529b8e80941Smrg      src_bit_sizes[1] = glsl_get_bit_size(dst->type);
530b8e80941Smrg      /* Also allow 32-bit boolean store operations */
531b8e80941Smrg      if (glsl_type_is_boolean(dst->type))
532b8e80941Smrg         src_bit_sizes[1] |= 32;
533b8e80941Smrg      validate_assert(state, (dst->mode & (nir_var_shader_in |
534b8e80941Smrg                                           nir_var_uniform)) == 0);
535b8e80941Smrg      validate_assert(state, (nir_intrinsic_write_mask(instr) & ~((1 << instr->num_components) - 1)) == 0);
536b8e80941Smrg      break;
537b8e80941Smrg   }
538b8e80941Smrg
539b8e80941Smrg   case nir_intrinsic_copy_deref: {
540b8e80941Smrg      nir_deref_instr *dst = nir_src_as_deref(instr->src[0]);
541b8e80941Smrg      nir_deref_instr *src = nir_src_as_deref(instr->src[1]);
542b8e80941Smrg      validate_assert(state, glsl_get_bare_type(dst->type) ==
543b8e80941Smrg                             glsl_get_bare_type(src->type));
544b8e80941Smrg      validate_assert(state, (dst->mode & (nir_var_shader_in |
545b8e80941Smrg                                           nir_var_uniform)) == 0);
546b8e80941Smrg      break;
547b8e80941Smrg   }
548b8e80941Smrg
549b8e80941Smrg   default:
550b8e80941Smrg      break;
551b8e80941Smrg   }
552b8e80941Smrg
553b8e80941Smrg   unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
554b8e80941Smrg   for (unsigned i = 0; i < num_srcs; i++) {
555b8e80941Smrg      unsigned components_read = nir_intrinsic_src_components(instr, i);
556b8e80941Smrg
557b8e80941Smrg      validate_assert(state, components_read > 0);
558b8e80941Smrg
559b8e80941Smrg      validate_src(&instr->src[i], state, src_bit_sizes[i], components_read);
560b8e80941Smrg   }
561b8e80941Smrg
562b8e80941Smrg   if (nir_intrinsic_infos[instr->intrinsic].has_dest) {
563b8e80941Smrg      unsigned components_written = nir_intrinsic_dest_components(instr);
564b8e80941Smrg      unsigned bit_sizes = nir_intrinsic_infos[instr->intrinsic].dest_bit_sizes;
565b8e80941Smrg
566b8e80941Smrg      validate_assert(state, components_written > 0);
567b8e80941Smrg
568b8e80941Smrg      if (dest_bit_size && bit_sizes)
569b8e80941Smrg         validate_assert(state, dest_bit_size & bit_sizes);
570b8e80941Smrg      else
571b8e80941Smrg         dest_bit_size = dest_bit_size ? dest_bit_size : bit_sizes;
572b8e80941Smrg
573b8e80941Smrg      validate_dest(&instr->dest, state, dest_bit_size, components_written);
574b8e80941Smrg   }
575b8e80941Smrg}
576b8e80941Smrg
577b8e80941Smrgstatic void
578b8e80941Smrgvalidate_tex_instr(nir_tex_instr *instr, validate_state *state)
579b8e80941Smrg{
580b8e80941Smrg   bool src_type_seen[nir_num_tex_src_types];
581b8e80941Smrg   for (unsigned i = 0; i < nir_num_tex_src_types; i++)
582b8e80941Smrg      src_type_seen[i] = false;
583b8e80941Smrg
584b8e80941Smrg   for (unsigned i = 0; i < instr->num_srcs; i++) {
585b8e80941Smrg      validate_assert(state, !src_type_seen[instr->src[i].src_type]);
586b8e80941Smrg      src_type_seen[instr->src[i].src_type] = true;
587b8e80941Smrg      validate_src(&instr->src[i].src, state,
588b8e80941Smrg                   0, nir_tex_instr_src_size(instr, i));
589b8e80941Smrg
590b8e80941Smrg      switch (instr->src[i].src_type) {
591b8e80941Smrg      case nir_tex_src_texture_deref:
592b8e80941Smrg      case nir_tex_src_sampler_deref:
593b8e80941Smrg         validate_assert(state, instr->src[i].src.is_ssa);
594b8e80941Smrg         validate_assert(state,
595b8e80941Smrg                         instr->src[i].src.ssa->parent_instr->type == nir_instr_type_deref);
596b8e80941Smrg         break;
597b8e80941Smrg      default:
598b8e80941Smrg         break;
599b8e80941Smrg      }
600b8e80941Smrg   }
601b8e80941Smrg
602b8e80941Smrg   if (nir_tex_instr_has_explicit_tg4_offsets(instr)) {
603b8e80941Smrg      validate_assert(state, instr->op == nir_texop_tg4);
604b8e80941Smrg      validate_assert(state, !src_type_seen[nir_tex_src_offset]);
605b8e80941Smrg   }
606b8e80941Smrg
607b8e80941Smrg   validate_dest(&instr->dest, state, 0, nir_tex_instr_dest_size(instr));
608b8e80941Smrg}
609b8e80941Smrg
610b8e80941Smrgstatic void
611b8e80941Smrgvalidate_call_instr(nir_call_instr *instr, validate_state *state)
612b8e80941Smrg{
613b8e80941Smrg   validate_assert(state, instr->num_params == instr->callee->num_params);
614b8e80941Smrg
615b8e80941Smrg   for (unsigned i = 0; i < instr->num_params; i++) {
616b8e80941Smrg      validate_src(&instr->params[i], state,
617b8e80941Smrg                   instr->callee->params[i].bit_size,
618b8e80941Smrg                   instr->callee->params[i].num_components);
619b8e80941Smrg   }
620b8e80941Smrg}
621b8e80941Smrg
622b8e80941Smrgstatic void
623b8e80941Smrgvalidate_const_value(nir_const_value *val, unsigned bit_size,
624b8e80941Smrg                     validate_state *state)
625b8e80941Smrg{
626b8e80941Smrg   /* In order for block copies to work properly for things like instruction
627b8e80941Smrg    * comparisons and [de]serialization, we require the unused bits of the
628b8e80941Smrg    * nir_const_value to be zero.
629b8e80941Smrg    */
630b8e80941Smrg   nir_const_value cmp_val;
631b8e80941Smrg   memset(&cmp_val, 0, sizeof(cmp_val));
632b8e80941Smrg   switch (bit_size) {
633b8e80941Smrg   case 1:
634b8e80941Smrg      cmp_val.b = val->b;
635b8e80941Smrg      break;
636b8e80941Smrg   case 8:
637b8e80941Smrg      cmp_val.u8 = val->u8;
638b8e80941Smrg      break;
639b8e80941Smrg   case 16:
640b8e80941Smrg      cmp_val.u16 = val->u16;
641b8e80941Smrg      break;
642b8e80941Smrg   case 32:
643b8e80941Smrg      cmp_val.u32 = val->u32;
644b8e80941Smrg      break;
645b8e80941Smrg   case 64:
646b8e80941Smrg      cmp_val.u64 = val->u64;
647b8e80941Smrg      break;
648b8e80941Smrg   default:
649b8e80941Smrg      validate_assert(state, !"Invalid load_const bit size");
650b8e80941Smrg   }
651b8e80941Smrg   validate_assert(state, memcmp(val, &cmp_val, sizeof(cmp_val)) == 0);
652b8e80941Smrg}
653b8e80941Smrg
654b8e80941Smrgstatic void
655b8e80941Smrgvalidate_load_const_instr(nir_load_const_instr *instr, validate_state *state)
656b8e80941Smrg{
657b8e80941Smrg   validate_ssa_def(&instr->def, state);
658b8e80941Smrg
659b8e80941Smrg   for (unsigned i = 0; i < instr->def.num_components; i++)
660b8e80941Smrg      validate_const_value(&instr->value[i], instr->def.bit_size, state);
661b8e80941Smrg}
662b8e80941Smrg
663b8e80941Smrgstatic void
664b8e80941Smrgvalidate_ssa_undef_instr(nir_ssa_undef_instr *instr, validate_state *state)
665b8e80941Smrg{
666b8e80941Smrg   validate_ssa_def(&instr->def, state);
667b8e80941Smrg}
668b8e80941Smrg
669b8e80941Smrgstatic void
670b8e80941Smrgvalidate_phi_instr(nir_phi_instr *instr, validate_state *state)
671b8e80941Smrg{
672b8e80941Smrg   /*
673b8e80941Smrg    * don't validate the sources until we get to them from their predecessor
674b8e80941Smrg    * basic blocks, to avoid validating an SSA use before its definition.
675b8e80941Smrg    */
676b8e80941Smrg
677b8e80941Smrg   validate_dest(&instr->dest, state, 0, 0);
678b8e80941Smrg
679b8e80941Smrg   exec_list_validate(&instr->srcs);
680b8e80941Smrg   validate_assert(state, exec_list_length(&instr->srcs) ==
681b8e80941Smrg          state->block->predecessors->entries);
682b8e80941Smrg}
683b8e80941Smrg
684b8e80941Smrgstatic void
685b8e80941Smrgvalidate_instr(nir_instr *instr, validate_state *state)
686b8e80941Smrg{
687b8e80941Smrg   validate_assert(state, instr->block == state->block);
688b8e80941Smrg
689b8e80941Smrg   state->instr = instr;
690b8e80941Smrg
691b8e80941Smrg   switch (instr->type) {
692b8e80941Smrg   case nir_instr_type_alu:
693b8e80941Smrg      validate_alu_instr(nir_instr_as_alu(instr), state);
694b8e80941Smrg      break;
695b8e80941Smrg
696b8e80941Smrg   case nir_instr_type_deref:
697b8e80941Smrg      validate_deref_instr(nir_instr_as_deref(instr), state);
698b8e80941Smrg      break;
699b8e80941Smrg
700b8e80941Smrg   case nir_instr_type_call:
701b8e80941Smrg      validate_call_instr(nir_instr_as_call(instr), state);
702b8e80941Smrg      break;
703b8e80941Smrg
704b8e80941Smrg   case nir_instr_type_intrinsic:
705b8e80941Smrg      validate_intrinsic_instr(nir_instr_as_intrinsic(instr), state);
706b8e80941Smrg      break;
707b8e80941Smrg
708b8e80941Smrg   case nir_instr_type_tex:
709b8e80941Smrg      validate_tex_instr(nir_instr_as_tex(instr), state);
710b8e80941Smrg      break;
711b8e80941Smrg
712b8e80941Smrg   case nir_instr_type_load_const:
713b8e80941Smrg      validate_load_const_instr(nir_instr_as_load_const(instr), state);
714b8e80941Smrg      break;
715b8e80941Smrg
716b8e80941Smrg   case nir_instr_type_phi:
717b8e80941Smrg      validate_phi_instr(nir_instr_as_phi(instr), state);
718b8e80941Smrg      break;
719b8e80941Smrg
720b8e80941Smrg   case nir_instr_type_ssa_undef:
721b8e80941Smrg      validate_ssa_undef_instr(nir_instr_as_ssa_undef(instr), state);
722b8e80941Smrg      break;
723b8e80941Smrg
724b8e80941Smrg   case nir_instr_type_jump:
725b8e80941Smrg      break;
726b8e80941Smrg
727b8e80941Smrg   default:
728b8e80941Smrg      validate_assert(state, !"Invalid ALU instruction type");
729b8e80941Smrg      break;
730b8e80941Smrg   }
731b8e80941Smrg
732b8e80941Smrg   state->instr = NULL;
733b8e80941Smrg}
734b8e80941Smrg
735b8e80941Smrgstatic void
736b8e80941Smrgvalidate_phi_src(nir_phi_instr *instr, nir_block *pred, validate_state *state)
737b8e80941Smrg{
738b8e80941Smrg   state->instr = &instr->instr;
739b8e80941Smrg
740b8e80941Smrg   validate_assert(state, instr->dest.is_ssa);
741b8e80941Smrg
742b8e80941Smrg   exec_list_validate(&instr->srcs);
743b8e80941Smrg   nir_foreach_phi_src(src, instr) {
744b8e80941Smrg      if (src->pred == pred) {
745b8e80941Smrg         validate_assert(state, src->src.is_ssa);
746b8e80941Smrg         validate_src(&src->src, state, instr->dest.ssa.bit_size,
747b8e80941Smrg                      instr->dest.ssa.num_components);
748b8e80941Smrg         state->instr = NULL;
749b8e80941Smrg         return;
750b8e80941Smrg      }
751b8e80941Smrg   }
752b8e80941Smrg
753b8e80941Smrg   abort();
754b8e80941Smrg}
755b8e80941Smrg
756b8e80941Smrgstatic void
757b8e80941Smrgvalidate_phi_srcs(nir_block *block, nir_block *succ, validate_state *state)
758b8e80941Smrg{
759b8e80941Smrg   nir_foreach_instr(instr, succ) {
760b8e80941Smrg      if (instr->type != nir_instr_type_phi)
761b8e80941Smrg         break;
762b8e80941Smrg
763b8e80941Smrg      validate_phi_src(nir_instr_as_phi(instr), block, state);
764b8e80941Smrg   }
765b8e80941Smrg}
766b8e80941Smrg
767b8e80941Smrgstatic void validate_cf_node(nir_cf_node *node, validate_state *state);
768b8e80941Smrg
769b8e80941Smrgstatic void
770b8e80941Smrgvalidate_block(nir_block *block, validate_state *state)
771b8e80941Smrg{
772b8e80941Smrg   validate_assert(state, block->cf_node.parent == state->parent_node);
773b8e80941Smrg
774b8e80941Smrg   state->block = block;
775b8e80941Smrg
776b8e80941Smrg   exec_list_validate(&block->instr_list);
777b8e80941Smrg   nir_foreach_instr(instr, block) {
778b8e80941Smrg      if (instr->type == nir_instr_type_phi) {
779b8e80941Smrg         validate_assert(state, instr == nir_block_first_instr(block) ||
780b8e80941Smrg                nir_instr_prev(instr)->type == nir_instr_type_phi);
781b8e80941Smrg      }
782b8e80941Smrg
783b8e80941Smrg      if (instr->type == nir_instr_type_jump) {
784b8e80941Smrg         validate_assert(state, instr == nir_block_last_instr(block));
785b8e80941Smrg      }
786b8e80941Smrg
787b8e80941Smrg      validate_instr(instr, state);
788b8e80941Smrg   }
789b8e80941Smrg
790b8e80941Smrg   validate_assert(state, block->successors[0] != NULL);
791b8e80941Smrg   validate_assert(state, block->successors[0] != block->successors[1]);
792b8e80941Smrg
793b8e80941Smrg   for (unsigned i = 0; i < 2; i++) {
794b8e80941Smrg      if (block->successors[i] != NULL) {
795b8e80941Smrg         struct set_entry *entry =
796b8e80941Smrg            _mesa_set_search(block->successors[i]->predecessors, block);
797b8e80941Smrg         validate_assert(state, entry);
798b8e80941Smrg
799b8e80941Smrg         validate_phi_srcs(block, block->successors[i], state);
800b8e80941Smrg      }
801b8e80941Smrg   }
802b8e80941Smrg
803b8e80941Smrg   set_foreach(block->predecessors, entry) {
804b8e80941Smrg      const nir_block *pred = entry->key;
805b8e80941Smrg      validate_assert(state, pred->successors[0] == block ||
806b8e80941Smrg             pred->successors[1] == block);
807b8e80941Smrg   }
808b8e80941Smrg
809b8e80941Smrg   if (!exec_list_is_empty(&block->instr_list) &&
810b8e80941Smrg       nir_block_last_instr(block)->type == nir_instr_type_jump) {
811b8e80941Smrg      validate_assert(state, block->successors[1] == NULL);
812b8e80941Smrg      nir_jump_instr *jump = nir_instr_as_jump(nir_block_last_instr(block));
813b8e80941Smrg      switch (jump->type) {
814b8e80941Smrg      case nir_jump_break: {
815b8e80941Smrg         nir_block *after =
816b8e80941Smrg            nir_cf_node_as_block(nir_cf_node_next(&state->loop->cf_node));
817b8e80941Smrg         validate_assert(state, block->successors[0] == after);
818b8e80941Smrg         break;
819b8e80941Smrg      }
820b8e80941Smrg
821b8e80941Smrg      case nir_jump_continue: {
822b8e80941Smrg         nir_block *first = nir_loop_first_block(state->loop);
823b8e80941Smrg         validate_assert(state, block->successors[0] == first);
824b8e80941Smrg         break;
825b8e80941Smrg      }
826b8e80941Smrg
827b8e80941Smrg      case nir_jump_return:
828b8e80941Smrg         validate_assert(state, block->successors[0] == state->impl->end_block);
829b8e80941Smrg         break;
830b8e80941Smrg
831b8e80941Smrg      default:
832b8e80941Smrg         unreachable("bad jump type");
833b8e80941Smrg      }
834b8e80941Smrg   } else {
835b8e80941Smrg      nir_cf_node *next = nir_cf_node_next(&block->cf_node);
836b8e80941Smrg      if (next == NULL) {
837b8e80941Smrg         switch (state->parent_node->type) {
838b8e80941Smrg         case nir_cf_node_loop: {
839b8e80941Smrg            nir_block *first = nir_loop_first_block(state->loop);
840b8e80941Smrg            validate_assert(state, block->successors[0] == first);
841b8e80941Smrg            /* due to the hack for infinite loops, block->successors[1] may
842b8e80941Smrg             * point to the block after the loop.
843b8e80941Smrg             */
844b8e80941Smrg            break;
845b8e80941Smrg         }
846b8e80941Smrg
847b8e80941Smrg         case nir_cf_node_if: {
848b8e80941Smrg            nir_block *after =
849b8e80941Smrg               nir_cf_node_as_block(nir_cf_node_next(state->parent_node));
850b8e80941Smrg            validate_assert(state, block->successors[0] == after);
851b8e80941Smrg            validate_assert(state, block->successors[1] == NULL);
852b8e80941Smrg            break;
853b8e80941Smrg         }
854b8e80941Smrg
855b8e80941Smrg         case nir_cf_node_function:
856b8e80941Smrg            validate_assert(state, block->successors[0] == state->impl->end_block);
857b8e80941Smrg            validate_assert(state, block->successors[1] == NULL);
858b8e80941Smrg            break;
859b8e80941Smrg
860b8e80941Smrg         default:
861b8e80941Smrg            unreachable("unknown control flow node type");
862b8e80941Smrg         }
863b8e80941Smrg      } else {
864b8e80941Smrg         if (next->type == nir_cf_node_if) {
865b8e80941Smrg            nir_if *if_stmt = nir_cf_node_as_if(next);
866b8e80941Smrg            validate_assert(state, block->successors[0] ==
867b8e80941Smrg                   nir_if_first_then_block(if_stmt));
868b8e80941Smrg            validate_assert(state, block->successors[1] ==
869b8e80941Smrg                   nir_if_first_else_block(if_stmt));
870b8e80941Smrg         } else {
871b8e80941Smrg            validate_assert(state, next->type == nir_cf_node_loop);
872b8e80941Smrg            nir_loop *loop = nir_cf_node_as_loop(next);
873b8e80941Smrg            validate_assert(state, block->successors[0] ==
874b8e80941Smrg                   nir_loop_first_block(loop));
875b8e80941Smrg            validate_assert(state, block->successors[1] == NULL);
876b8e80941Smrg         }
877b8e80941Smrg      }
878b8e80941Smrg   }
879b8e80941Smrg}
880b8e80941Smrg
881b8e80941Smrgstatic void
882b8e80941Smrgvalidate_if(nir_if *if_stmt, validate_state *state)
883b8e80941Smrg{
884b8e80941Smrg   state->if_stmt = if_stmt;
885b8e80941Smrg
886b8e80941Smrg   validate_assert(state, !exec_node_is_head_sentinel(if_stmt->cf_node.node.prev));
887b8e80941Smrg   nir_cf_node *prev_node = nir_cf_node_prev(&if_stmt->cf_node);
888b8e80941Smrg   validate_assert(state, prev_node->type == nir_cf_node_block);
889b8e80941Smrg
890b8e80941Smrg   validate_assert(state, !exec_node_is_tail_sentinel(if_stmt->cf_node.node.next));
891b8e80941Smrg   nir_cf_node *next_node = nir_cf_node_next(&if_stmt->cf_node);
892b8e80941Smrg   validate_assert(state, next_node->type == nir_cf_node_block);
893b8e80941Smrg
894b8e80941Smrg   validate_src(&if_stmt->condition, state, 0, 1);
895b8e80941Smrg
896b8e80941Smrg   validate_assert(state, !exec_list_is_empty(&if_stmt->then_list));
897b8e80941Smrg   validate_assert(state, !exec_list_is_empty(&if_stmt->else_list));
898b8e80941Smrg
899b8e80941Smrg   nir_cf_node *old_parent = state->parent_node;
900b8e80941Smrg   state->parent_node = &if_stmt->cf_node;
901b8e80941Smrg
902b8e80941Smrg   exec_list_validate(&if_stmt->then_list);
903b8e80941Smrg   foreach_list_typed(nir_cf_node, cf_node, node, &if_stmt->then_list) {
904b8e80941Smrg      validate_cf_node(cf_node, state);
905b8e80941Smrg   }
906b8e80941Smrg
907b8e80941Smrg   exec_list_validate(&if_stmt->else_list);
908b8e80941Smrg   foreach_list_typed(nir_cf_node, cf_node, node, &if_stmt->else_list) {
909b8e80941Smrg      validate_cf_node(cf_node, state);
910b8e80941Smrg   }
911b8e80941Smrg
912b8e80941Smrg   state->parent_node = old_parent;
913b8e80941Smrg   state->if_stmt = NULL;
914b8e80941Smrg}
915b8e80941Smrg
916b8e80941Smrgstatic void
917b8e80941Smrgvalidate_loop(nir_loop *loop, validate_state *state)
918b8e80941Smrg{
919b8e80941Smrg   validate_assert(state, !exec_node_is_head_sentinel(loop->cf_node.node.prev));
920b8e80941Smrg   nir_cf_node *prev_node = nir_cf_node_prev(&loop->cf_node);
921b8e80941Smrg   validate_assert(state, prev_node->type == nir_cf_node_block);
922b8e80941Smrg
923b8e80941Smrg   validate_assert(state, !exec_node_is_tail_sentinel(loop->cf_node.node.next));
924b8e80941Smrg   nir_cf_node *next_node = nir_cf_node_next(&loop->cf_node);
925b8e80941Smrg   validate_assert(state, next_node->type == nir_cf_node_block);
926b8e80941Smrg
927b8e80941Smrg   validate_assert(state, !exec_list_is_empty(&loop->body));
928b8e80941Smrg
929b8e80941Smrg   nir_cf_node *old_parent = state->parent_node;
930b8e80941Smrg   state->parent_node = &loop->cf_node;
931b8e80941Smrg   nir_loop *old_loop = state->loop;
932b8e80941Smrg   state->loop = loop;
933b8e80941Smrg
934b8e80941Smrg   exec_list_validate(&loop->body);
935b8e80941Smrg   foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) {
936b8e80941Smrg      validate_cf_node(cf_node, state);
937b8e80941Smrg   }
938b8e80941Smrg
939b8e80941Smrg   state->parent_node = old_parent;
940b8e80941Smrg   state->loop = old_loop;
941b8e80941Smrg}
942b8e80941Smrg
943b8e80941Smrgstatic void
944b8e80941Smrgvalidate_cf_node(nir_cf_node *node, validate_state *state)
945b8e80941Smrg{
946b8e80941Smrg   validate_assert(state, node->parent == state->parent_node);
947b8e80941Smrg
948b8e80941Smrg   switch (node->type) {
949b8e80941Smrg   case nir_cf_node_block:
950b8e80941Smrg      validate_block(nir_cf_node_as_block(node), state);
951b8e80941Smrg      break;
952b8e80941Smrg
953b8e80941Smrg   case nir_cf_node_if:
954b8e80941Smrg      validate_if(nir_cf_node_as_if(node), state);
955b8e80941Smrg      break;
956b8e80941Smrg
957b8e80941Smrg   case nir_cf_node_loop:
958b8e80941Smrg      validate_loop(nir_cf_node_as_loop(node), state);
959b8e80941Smrg      break;
960b8e80941Smrg
961b8e80941Smrg   default:
962b8e80941Smrg      unreachable("Invalid CF node type");
963b8e80941Smrg   }
964b8e80941Smrg}
965b8e80941Smrg
966b8e80941Smrgstatic void
967b8e80941Smrgprevalidate_reg_decl(nir_register *reg, validate_state *state)
968b8e80941Smrg{
969b8e80941Smrg   validate_assert(state, reg->index < state->impl->reg_alloc);
970b8e80941Smrg   validate_assert(state, !BITSET_TEST(state->regs_found, reg->index));
971b8e80941Smrg   BITSET_SET(state->regs_found, reg->index);
972b8e80941Smrg
973b8e80941Smrg   list_validate(&reg->uses);
974b8e80941Smrg   list_validate(&reg->defs);
975b8e80941Smrg   list_validate(&reg->if_uses);
976b8e80941Smrg
977b8e80941Smrg   reg_validate_state *reg_state = ralloc(state->regs, reg_validate_state);
978b8e80941Smrg   reg_state->uses = _mesa_pointer_set_create(reg_state);
979b8e80941Smrg   reg_state->if_uses = _mesa_pointer_set_create(reg_state);
980b8e80941Smrg   reg_state->defs = _mesa_pointer_set_create(reg_state);
981b8e80941Smrg
982b8e80941Smrg   reg_state->where_defined = state->impl;
983b8e80941Smrg
984b8e80941Smrg   _mesa_hash_table_insert(state->regs, reg, reg_state);
985b8e80941Smrg}
986b8e80941Smrg
987b8e80941Smrgstatic void
988b8e80941Smrgpostvalidate_reg_decl(nir_register *reg, validate_state *state)
989b8e80941Smrg{
990b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->regs, reg);
991b8e80941Smrg
992b8e80941Smrg   assume(entry);
993b8e80941Smrg   reg_validate_state *reg_state = (reg_validate_state *) entry->data;
994b8e80941Smrg
995b8e80941Smrg   nir_foreach_use(src, reg) {
996b8e80941Smrg      struct set_entry *entry = _mesa_set_search(reg_state->uses, src);
997b8e80941Smrg      validate_assert(state, entry);
998b8e80941Smrg      _mesa_set_remove(reg_state->uses, entry);
999b8e80941Smrg   }
1000b8e80941Smrg
1001b8e80941Smrg   if (reg_state->uses->entries != 0) {
1002b8e80941Smrg      printf("extra entries in register uses:\n");
1003b8e80941Smrg      set_foreach(reg_state->uses, entry)
1004b8e80941Smrg         printf("%p\n", entry->key);
1005b8e80941Smrg
1006b8e80941Smrg      abort();
1007b8e80941Smrg   }
1008b8e80941Smrg
1009b8e80941Smrg   nir_foreach_if_use(src, reg) {
1010b8e80941Smrg      struct set_entry *entry = _mesa_set_search(reg_state->if_uses, src);
1011b8e80941Smrg      validate_assert(state, entry);
1012b8e80941Smrg      _mesa_set_remove(reg_state->if_uses, entry);
1013b8e80941Smrg   }
1014b8e80941Smrg
1015b8e80941Smrg   if (reg_state->if_uses->entries != 0) {
1016b8e80941Smrg      printf("extra entries in register if_uses:\n");
1017b8e80941Smrg      set_foreach(reg_state->if_uses, entry)
1018b8e80941Smrg         printf("%p\n", entry->key);
1019b8e80941Smrg
1020b8e80941Smrg      abort();
1021b8e80941Smrg   }
1022b8e80941Smrg
1023b8e80941Smrg   nir_foreach_def(src, reg) {
1024b8e80941Smrg      struct set_entry *entry = _mesa_set_search(reg_state->defs, src);
1025b8e80941Smrg      validate_assert(state, entry);
1026b8e80941Smrg      _mesa_set_remove(reg_state->defs, entry);
1027b8e80941Smrg   }
1028b8e80941Smrg
1029b8e80941Smrg   if (reg_state->defs->entries != 0) {
1030b8e80941Smrg      printf("extra entries in register defs:\n");
1031b8e80941Smrg      set_foreach(reg_state->defs, entry)
1032b8e80941Smrg         printf("%p\n", entry->key);
1033b8e80941Smrg
1034b8e80941Smrg      abort();
1035b8e80941Smrg   }
1036b8e80941Smrg}
1037b8e80941Smrg
1038b8e80941Smrgstatic void
1039b8e80941Smrgvalidate_var_decl(nir_variable *var, bool is_global, validate_state *state)
1040b8e80941Smrg{
1041b8e80941Smrg   state->var = var;
1042b8e80941Smrg
1043b8e80941Smrg   validate_assert(state, is_global == nir_variable_is_global(var));
1044b8e80941Smrg
1045b8e80941Smrg   /* Must have exactly one mode set */
1046b8e80941Smrg   validate_assert(state, util_is_power_of_two_nonzero(var->data.mode));
1047b8e80941Smrg
1048b8e80941Smrg   if (var->data.compact) {
1049b8e80941Smrg      /* The "compact" flag is only valid on arrays of scalars. */
1050b8e80941Smrg      assert(glsl_type_is_array(var->type));
1051b8e80941Smrg
1052b8e80941Smrg      const struct glsl_type *type = glsl_get_array_element(var->type);
1053b8e80941Smrg      if (nir_is_per_vertex_io(var, state->shader->info.stage)) {
1054b8e80941Smrg         assert(glsl_type_is_array(type));
1055b8e80941Smrg         assert(glsl_type_is_scalar(glsl_get_array_element(type)));
1056b8e80941Smrg      } else {
1057b8e80941Smrg         assert(glsl_type_is_scalar(type));
1058b8e80941Smrg      }
1059b8e80941Smrg   }
1060b8e80941Smrg
1061b8e80941Smrg   if (var->num_members > 0) {
1062b8e80941Smrg      const struct glsl_type *without_array = glsl_without_array(var->type);
1063b8e80941Smrg      validate_assert(state, glsl_type_is_struct_or_ifc(without_array));
1064b8e80941Smrg      validate_assert(state, var->num_members == glsl_get_length(without_array));
1065b8e80941Smrg      validate_assert(state, var->members != NULL);
1066b8e80941Smrg   }
1067b8e80941Smrg
1068b8e80941Smrg   /*
1069b8e80941Smrg    * TODO validate some things ir_validate.cpp does (requires more GLSL type
1070b8e80941Smrg    * support)
1071b8e80941Smrg    */
1072b8e80941Smrg
1073b8e80941Smrg   _mesa_hash_table_insert(state->var_defs, var,
1074b8e80941Smrg                           is_global ? NULL : state->impl);
1075b8e80941Smrg
1076b8e80941Smrg   state->var = NULL;
1077b8e80941Smrg}
1078b8e80941Smrg
1079b8e80941Smrgstatic bool
1080b8e80941Smrgpostvalidate_ssa_def(nir_ssa_def *def, void *void_state)
1081b8e80941Smrg{
1082b8e80941Smrg   validate_state *state = void_state;
1083b8e80941Smrg
1084b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs, def);
1085b8e80941Smrg
1086b8e80941Smrg   assume(entry);
1087b8e80941Smrg   ssa_def_validate_state *def_state = (ssa_def_validate_state *)entry->data;
1088b8e80941Smrg
1089b8e80941Smrg   nir_foreach_use(src, def) {
1090b8e80941Smrg      struct set_entry *entry = _mesa_set_search(def_state->uses, src);
1091b8e80941Smrg      validate_assert(state, entry);
1092b8e80941Smrg      _mesa_set_remove(def_state->uses, entry);
1093b8e80941Smrg   }
1094b8e80941Smrg
1095b8e80941Smrg   if (def_state->uses->entries != 0) {
1096b8e80941Smrg      printf("extra entries in SSA def uses:\n");
1097b8e80941Smrg      set_foreach(def_state->uses, entry)
1098b8e80941Smrg         printf("%p\n", entry->key);
1099b8e80941Smrg
1100b8e80941Smrg      abort();
1101b8e80941Smrg   }
1102b8e80941Smrg
1103b8e80941Smrg   nir_foreach_if_use(src, def) {
1104b8e80941Smrg      struct set_entry *entry = _mesa_set_search(def_state->if_uses, src);
1105b8e80941Smrg      validate_assert(state, entry);
1106b8e80941Smrg      _mesa_set_remove(def_state->if_uses, entry);
1107b8e80941Smrg   }
1108b8e80941Smrg
1109b8e80941Smrg   if (def_state->if_uses->entries != 0) {
1110b8e80941Smrg      printf("extra entries in SSA def uses:\n");
1111b8e80941Smrg      set_foreach(def_state->if_uses, entry)
1112b8e80941Smrg         printf("%p\n", entry->key);
1113b8e80941Smrg
1114b8e80941Smrg      abort();
1115b8e80941Smrg   }
1116b8e80941Smrg
1117b8e80941Smrg   return true;
1118b8e80941Smrg}
1119b8e80941Smrg
1120b8e80941Smrgstatic void
1121b8e80941Smrgvalidate_function_impl(nir_function_impl *impl, validate_state *state)
1122b8e80941Smrg{
1123b8e80941Smrg   validate_assert(state, impl->function->impl == impl);
1124b8e80941Smrg   validate_assert(state, impl->cf_node.parent == NULL);
1125b8e80941Smrg
1126b8e80941Smrg   validate_assert(state, exec_list_is_empty(&impl->end_block->instr_list));
1127b8e80941Smrg   validate_assert(state, impl->end_block->successors[0] == NULL);
1128b8e80941Smrg   validate_assert(state, impl->end_block->successors[1] == NULL);
1129b8e80941Smrg
1130b8e80941Smrg   state->impl = impl;
1131b8e80941Smrg   state->parent_node = &impl->cf_node;
1132b8e80941Smrg
1133b8e80941Smrg   exec_list_validate(&impl->locals);
1134b8e80941Smrg   nir_foreach_variable(var, &impl->locals) {
1135b8e80941Smrg      validate_var_decl(var, false, state);
1136b8e80941Smrg   }
1137b8e80941Smrg
1138b8e80941Smrg   state->regs_found = realloc(state->regs_found,
1139b8e80941Smrg                               BITSET_WORDS(impl->reg_alloc) *
1140b8e80941Smrg                               sizeof(BITSET_WORD));
1141b8e80941Smrg   memset(state->regs_found, 0, BITSET_WORDS(impl->reg_alloc) *
1142b8e80941Smrg                                sizeof(BITSET_WORD));
1143b8e80941Smrg   exec_list_validate(&impl->registers);
1144b8e80941Smrg   foreach_list_typed(nir_register, reg, node, &impl->registers) {
1145b8e80941Smrg      prevalidate_reg_decl(reg, state);
1146b8e80941Smrg   }
1147b8e80941Smrg
1148b8e80941Smrg   state->ssa_defs_found = realloc(state->ssa_defs_found,
1149b8e80941Smrg                                   BITSET_WORDS(impl->ssa_alloc) *
1150b8e80941Smrg                                   sizeof(BITSET_WORD));
1151b8e80941Smrg   memset(state->ssa_defs_found, 0, BITSET_WORDS(impl->ssa_alloc) *
1152b8e80941Smrg                                    sizeof(BITSET_WORD));
1153b8e80941Smrg   exec_list_validate(&impl->body);
1154b8e80941Smrg   foreach_list_typed(nir_cf_node, node, node, &impl->body) {
1155b8e80941Smrg      validate_cf_node(node, state);
1156b8e80941Smrg   }
1157b8e80941Smrg
1158b8e80941Smrg   foreach_list_typed(nir_register, reg, node, &impl->registers) {
1159b8e80941Smrg      postvalidate_reg_decl(reg, state);
1160b8e80941Smrg   }
1161b8e80941Smrg
1162b8e80941Smrg   nir_foreach_block(block, impl) {
1163b8e80941Smrg      nir_foreach_instr(instr, block)
1164b8e80941Smrg         nir_foreach_ssa_def(instr, postvalidate_ssa_def, state);
1165b8e80941Smrg   }
1166b8e80941Smrg}
1167b8e80941Smrg
1168b8e80941Smrgstatic void
1169b8e80941Smrgvalidate_function(nir_function *func, validate_state *state)
1170b8e80941Smrg{
1171b8e80941Smrg   if (func->impl != NULL) {
1172b8e80941Smrg      validate_assert(state, func->impl->function == func);
1173b8e80941Smrg      validate_function_impl(func->impl, state);
1174b8e80941Smrg   }
1175b8e80941Smrg}
1176b8e80941Smrg
1177b8e80941Smrgstatic void
1178b8e80941Smrginit_validate_state(validate_state *state)
1179b8e80941Smrg{
1180b8e80941Smrg   state->regs = _mesa_pointer_hash_table_create(NULL);
1181b8e80941Smrg   state->ssa_defs = _mesa_pointer_hash_table_create(NULL);
1182b8e80941Smrg   state->ssa_defs_found = NULL;
1183b8e80941Smrg   state->regs_found = NULL;
1184b8e80941Smrg   state->var_defs = _mesa_pointer_hash_table_create(NULL);
1185b8e80941Smrg   state->errors = _mesa_pointer_hash_table_create(NULL);
1186b8e80941Smrg
1187b8e80941Smrg   state->loop = NULL;
1188b8e80941Smrg   state->instr = NULL;
1189b8e80941Smrg   state->var = NULL;
1190b8e80941Smrg}
1191b8e80941Smrg
1192b8e80941Smrgstatic void
1193b8e80941Smrgdestroy_validate_state(validate_state *state)
1194b8e80941Smrg{
1195b8e80941Smrg   _mesa_hash_table_destroy(state->regs, NULL);
1196b8e80941Smrg   _mesa_hash_table_destroy(state->ssa_defs, NULL);
1197b8e80941Smrg   free(state->ssa_defs_found);
1198b8e80941Smrg   free(state->regs_found);
1199b8e80941Smrg   _mesa_hash_table_destroy(state->var_defs, NULL);
1200b8e80941Smrg   _mesa_hash_table_destroy(state->errors, NULL);
1201b8e80941Smrg}
1202b8e80941Smrg
1203b8e80941Smrgmtx_t fail_dump_mutex = _MTX_INITIALIZER_NP;
1204b8e80941Smrg
1205b8e80941Smrgstatic void
1206b8e80941Smrgdump_errors(validate_state *state, const char *when)
1207b8e80941Smrg{
1208b8e80941Smrg   struct hash_table *errors = state->errors;
1209b8e80941Smrg
1210b8e80941Smrg   /* Lock around dumping so that we get clean dumps in a multi-threaded
1211b8e80941Smrg    * scenario
1212b8e80941Smrg    */
1213b8e80941Smrg   mtx_lock(&fail_dump_mutex);
1214b8e80941Smrg
1215b8e80941Smrg   if (when) {
1216b8e80941Smrg      fprintf(stderr, "NIR validation failed %s\n", when);
1217b8e80941Smrg      fprintf(stderr, "%d errors:\n", _mesa_hash_table_num_entries(errors));
1218b8e80941Smrg   } else {
1219b8e80941Smrg      fprintf(stderr, "NIR validation failed with %d errors:\n",
1220b8e80941Smrg              _mesa_hash_table_num_entries(errors));
1221b8e80941Smrg   }
1222b8e80941Smrg
1223b8e80941Smrg   nir_print_shader_annotated(state->shader, stderr, errors);
1224b8e80941Smrg
1225b8e80941Smrg   if (_mesa_hash_table_num_entries(errors) > 0) {
1226b8e80941Smrg      fprintf(stderr, "%d additional errors:\n",
1227b8e80941Smrg              _mesa_hash_table_num_entries(errors));
1228b8e80941Smrg      hash_table_foreach(errors, entry) {
1229b8e80941Smrg         fprintf(stderr, "%s\n", (char *)entry->data);
1230b8e80941Smrg      }
1231b8e80941Smrg   }
1232b8e80941Smrg
1233b8e80941Smrg   mtx_unlock(&fail_dump_mutex);
1234b8e80941Smrg
1235b8e80941Smrg   abort();
1236b8e80941Smrg}
1237b8e80941Smrg
1238b8e80941Smrgvoid
1239b8e80941Smrgnir_validate_shader(nir_shader *shader, const char *when)
1240b8e80941Smrg{
1241b8e80941Smrg   static int should_validate = -1;
1242b8e80941Smrg   if (should_validate < 0)
1243b8e80941Smrg      should_validate = env_var_as_boolean("NIR_VALIDATE", true);
1244b8e80941Smrg   if (!should_validate)
1245b8e80941Smrg      return;
1246b8e80941Smrg
1247b8e80941Smrg   validate_state state;
1248b8e80941Smrg   init_validate_state(&state);
1249b8e80941Smrg
1250b8e80941Smrg   state.shader = shader;
1251b8e80941Smrg
1252b8e80941Smrg   exec_list_validate(&shader->uniforms);
1253b8e80941Smrg   nir_foreach_variable(var, &shader->uniforms) {
1254b8e80941Smrg      validate_var_decl(var, true, &state);
1255b8e80941Smrg   }
1256b8e80941Smrg
1257b8e80941Smrg   exec_list_validate(&shader->inputs);
1258b8e80941Smrg   nir_foreach_variable(var, &shader->inputs) {
1259b8e80941Smrg     validate_var_decl(var, true, &state);
1260b8e80941Smrg   }
1261b8e80941Smrg
1262b8e80941Smrg   exec_list_validate(&shader->outputs);
1263b8e80941Smrg   nir_foreach_variable(var, &shader->outputs) {
1264b8e80941Smrg     validate_var_decl(var, true, &state);
1265b8e80941Smrg   }
1266b8e80941Smrg
1267b8e80941Smrg   exec_list_validate(&shader->shared);
1268b8e80941Smrg   nir_foreach_variable(var, &shader->shared) {
1269b8e80941Smrg      validate_var_decl(var, true, &state);
1270b8e80941Smrg   }
1271b8e80941Smrg
1272b8e80941Smrg   exec_list_validate(&shader->globals);
1273b8e80941Smrg   nir_foreach_variable(var, &shader->globals) {
1274b8e80941Smrg     validate_var_decl(var, true, &state);
1275b8e80941Smrg   }
1276b8e80941Smrg
1277b8e80941Smrg   exec_list_validate(&shader->system_values);
1278b8e80941Smrg   nir_foreach_variable(var, &shader->system_values) {
1279b8e80941Smrg     validate_var_decl(var, true, &state);
1280b8e80941Smrg   }
1281b8e80941Smrg
1282b8e80941Smrg   exec_list_validate(&shader->functions);
1283b8e80941Smrg   foreach_list_typed(nir_function, func, node, &shader->functions) {
1284b8e80941Smrg      validate_function(func, &state);
1285b8e80941Smrg   }
1286b8e80941Smrg
1287b8e80941Smrg   if (_mesa_hash_table_num_entries(state.errors) > 0)
1288b8e80941Smrg      dump_errors(&state, when);
1289b8e80941Smrg
1290b8e80941Smrg   destroy_validate_state(&state);
1291b8e80941Smrg}
1292b8e80941Smrg
1293b8e80941Smrg#endif /* NDEBUG */
1294