1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2010 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
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg/**
25b8e80941Smrg * \file ir_validate.cpp
26b8e80941Smrg *
27b8e80941Smrg * Attempts to verify that various invariants of the IR tree are true.
28b8e80941Smrg *
29b8e80941Smrg * In particular, at the moment it makes sure that no single
30b8e80941Smrg * ir_instruction node except for ir_variable appears multiple times
31b8e80941Smrg * in the ir tree.  ir_variable does appear multiple times: Once as a
32b8e80941Smrg * declaration in an exec_list, and multiple times as the endpoint of
33b8e80941Smrg * a dereference chain.
34b8e80941Smrg */
35b8e80941Smrg
36b8e80941Smrg#include "ir.h"
37b8e80941Smrg#include "ir_hierarchical_visitor.h"
38b8e80941Smrg#include "util/hash_table.h"
39b8e80941Smrg#include "util/macros.h"
40b8e80941Smrg#include "util/set.h"
41b8e80941Smrg#include "compiler/glsl_types.h"
42b8e80941Smrg
43b8e80941Smrgnamespace {
44b8e80941Smrg
45b8e80941Smrgclass ir_validate : public ir_hierarchical_visitor {
46b8e80941Smrgpublic:
47b8e80941Smrg   ir_validate()
48b8e80941Smrg   {
49b8e80941Smrg      this->ir_set = _mesa_pointer_set_create(NULL);
50b8e80941Smrg
51b8e80941Smrg      this->current_function = NULL;
52b8e80941Smrg
53b8e80941Smrg      this->callback_enter = ir_validate::validate_ir;
54b8e80941Smrg      this->data_enter = ir_set;
55b8e80941Smrg   }
56b8e80941Smrg
57b8e80941Smrg   ~ir_validate()
58b8e80941Smrg   {
59b8e80941Smrg      _mesa_set_destroy(this->ir_set, NULL);
60b8e80941Smrg   }
61b8e80941Smrg
62b8e80941Smrg   virtual ir_visitor_status visit(ir_variable *v);
63b8e80941Smrg   virtual ir_visitor_status visit(ir_dereference_variable *ir);
64b8e80941Smrg
65b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_discard *ir);
66b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_if *ir);
67b8e80941Smrg
68b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_function *ir);
69b8e80941Smrg   virtual ir_visitor_status visit_leave(ir_function *ir);
70b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_function_signature *ir);
71b8e80941Smrg
72b8e80941Smrg   virtual ir_visitor_status visit_leave(ir_expression *ir);
73b8e80941Smrg   virtual ir_visitor_status visit_leave(ir_swizzle *ir);
74b8e80941Smrg
75b8e80941Smrg   virtual ir_visitor_status visit_enter(class ir_dereference_array *);
76b8e80941Smrg
77b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_assignment *ir);
78b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_call *ir);
79b8e80941Smrg
80b8e80941Smrg   static void validate_ir(ir_instruction *ir, void *data);
81b8e80941Smrg
82b8e80941Smrg   ir_function *current_function;
83b8e80941Smrg
84b8e80941Smrg   struct set *ir_set;
85b8e80941Smrg};
86b8e80941Smrg
87b8e80941Smrg} /* anonymous namespace */
88b8e80941Smrg
89b8e80941Smrgir_visitor_status
90b8e80941Smrgir_validate::visit(ir_dereference_variable *ir)
91b8e80941Smrg{
92b8e80941Smrg   if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
93b8e80941Smrg      printf("ir_dereference_variable @ %p does not specify a variable %p\n",
94b8e80941Smrg	     (void *) ir, (void *) ir->var);
95b8e80941Smrg      abort();
96b8e80941Smrg   }
97b8e80941Smrg
98b8e80941Smrg   if (_mesa_set_search(ir_set, ir->var) == NULL) {
99b8e80941Smrg      printf("ir_dereference_variable @ %p specifies undeclared variable "
100b8e80941Smrg	     "`%s' @ %p\n",
101b8e80941Smrg	     (void *) ir, ir->var->name, (void *) ir->var);
102b8e80941Smrg      abort();
103b8e80941Smrg   }
104b8e80941Smrg
105b8e80941Smrg   this->validate_ir(ir, this->data_enter);
106b8e80941Smrg
107b8e80941Smrg   return visit_continue;
108b8e80941Smrg}
109b8e80941Smrg
110b8e80941Smrgir_visitor_status
111b8e80941Smrgir_validate::visit_enter(class ir_dereference_array *ir)
112b8e80941Smrg{
113b8e80941Smrg   if (!ir->array->type->is_array() && !ir->array->type->is_matrix() &&
114b8e80941Smrg      !ir->array->type->is_vector()) {
115b8e80941Smrg      printf("ir_dereference_array @ %p does not specify an array, a vector "
116b8e80941Smrg             "or a matrix\n",
117b8e80941Smrg             (void *) ir);
118b8e80941Smrg      ir->print();
119b8e80941Smrg      printf("\n");
120b8e80941Smrg      abort();
121b8e80941Smrg   }
122b8e80941Smrg
123b8e80941Smrg   if (!ir->array_index->type->is_scalar()) {
124b8e80941Smrg      printf("ir_dereference_array @ %p does not have scalar index: %s\n",
125b8e80941Smrg             (void *) ir, ir->array_index->type->name);
126b8e80941Smrg      abort();
127b8e80941Smrg   }
128b8e80941Smrg
129b8e80941Smrg   if (!ir->array_index->type->is_integer()) {
130b8e80941Smrg      printf("ir_dereference_array @ %p does not have integer index: %s\n",
131b8e80941Smrg             (void *) ir, ir->array_index->type->name);
132b8e80941Smrg      abort();
133b8e80941Smrg   }
134b8e80941Smrg
135b8e80941Smrg   return visit_continue;
136b8e80941Smrg}
137b8e80941Smrg
138b8e80941Smrgir_visitor_status
139b8e80941Smrgir_validate::visit_enter(ir_discard *ir)
140b8e80941Smrg{
141b8e80941Smrg   if (ir->condition && ir->condition->type != glsl_type::bool_type) {
142b8e80941Smrg      printf("ir_discard condition %s type instead of bool.\n",
143b8e80941Smrg	     ir->condition->type->name);
144b8e80941Smrg      ir->print();
145b8e80941Smrg      printf("\n");
146b8e80941Smrg      abort();
147b8e80941Smrg   }
148b8e80941Smrg
149b8e80941Smrg   return visit_continue;
150b8e80941Smrg}
151b8e80941Smrg
152b8e80941Smrgir_visitor_status
153b8e80941Smrgir_validate::visit_enter(ir_if *ir)
154b8e80941Smrg{
155b8e80941Smrg   if (ir->condition->type != glsl_type::bool_type) {
156b8e80941Smrg      printf("ir_if condition %s type instead of bool.\n",
157b8e80941Smrg	     ir->condition->type->name);
158b8e80941Smrg      ir->print();
159b8e80941Smrg      printf("\n");
160b8e80941Smrg      abort();
161b8e80941Smrg   }
162b8e80941Smrg
163b8e80941Smrg   return visit_continue;
164b8e80941Smrg}
165b8e80941Smrg
166b8e80941Smrg
167b8e80941Smrgir_visitor_status
168b8e80941Smrgir_validate::visit_enter(ir_function *ir)
169b8e80941Smrg{
170b8e80941Smrg   /* Function definitions cannot be nested.
171b8e80941Smrg    */
172b8e80941Smrg   if (this->current_function != NULL) {
173b8e80941Smrg      printf("Function definition nested inside another function "
174b8e80941Smrg	     "definition:\n");
175b8e80941Smrg      printf("%s %p inside %s %p\n",
176b8e80941Smrg	     ir->name, (void *) ir,
177b8e80941Smrg	     this->current_function->name, (void *) this->current_function);
178b8e80941Smrg      abort();
179b8e80941Smrg   }
180b8e80941Smrg
181b8e80941Smrg   /* Store the current function hierarchy being traversed.  This is used
182b8e80941Smrg    * by the function signature visitor to ensure that the signatures are
183b8e80941Smrg    * linked with the correct functions.
184b8e80941Smrg    */
185b8e80941Smrg   this->current_function = ir;
186b8e80941Smrg
187b8e80941Smrg   this->validate_ir(ir, this->data_enter);
188b8e80941Smrg
189b8e80941Smrg   /* Verify that all of the things stored in the list of signatures are,
190b8e80941Smrg    * in fact, function signatures.
191b8e80941Smrg    */
192b8e80941Smrg   foreach_in_list(ir_instruction, sig, &ir->signatures) {
193b8e80941Smrg      if (sig->ir_type != ir_type_function_signature) {
194b8e80941Smrg	 printf("Non-signature in signature list of function `%s'\n",
195b8e80941Smrg		ir->name);
196b8e80941Smrg	 abort();
197b8e80941Smrg      }
198b8e80941Smrg   }
199b8e80941Smrg
200b8e80941Smrg   return visit_continue;
201b8e80941Smrg}
202b8e80941Smrg
203b8e80941Smrgir_visitor_status
204b8e80941Smrgir_validate::visit_leave(ir_function *ir)
205b8e80941Smrg{
206b8e80941Smrg   assert(ralloc_parent(ir->name) == ir);
207b8e80941Smrg
208b8e80941Smrg   this->current_function = NULL;
209b8e80941Smrg   return visit_continue;
210b8e80941Smrg}
211b8e80941Smrg
212b8e80941Smrgir_visitor_status
213b8e80941Smrgir_validate::visit_enter(ir_function_signature *ir)
214b8e80941Smrg{
215b8e80941Smrg   if (this->current_function != ir->function()) {
216b8e80941Smrg      printf("Function signature nested inside wrong function "
217b8e80941Smrg	     "definition:\n");
218b8e80941Smrg      printf("%p inside %s %p instead of %s %p\n",
219b8e80941Smrg	     (void *) ir,
220b8e80941Smrg	     this->current_function->name, (void *) this->current_function,
221b8e80941Smrg	     ir->function_name(), (void *) ir->function());
222b8e80941Smrg      abort();
223b8e80941Smrg   }
224b8e80941Smrg
225b8e80941Smrg   if (ir->return_type == NULL) {
226b8e80941Smrg      printf("Function signature %p for function %s has NULL return type.\n",
227b8e80941Smrg	     (void *) ir, ir->function_name());
228b8e80941Smrg      abort();
229b8e80941Smrg   }
230b8e80941Smrg
231b8e80941Smrg   this->validate_ir(ir, this->data_enter);
232b8e80941Smrg
233b8e80941Smrg   return visit_continue;
234b8e80941Smrg}
235b8e80941Smrg
236b8e80941Smrgir_visitor_status
237b8e80941Smrgir_validate::visit_leave(ir_expression *ir)
238b8e80941Smrg{
239b8e80941Smrg   for (unsigned i = ir->num_operands; i < 4; i++) {
240b8e80941Smrg      assert(ir->operands[i] == NULL);
241b8e80941Smrg   }
242b8e80941Smrg
243b8e80941Smrg   for (unsigned i = 0; i < ir->num_operands; i++) {
244b8e80941Smrg      assert(ir->operands[i] != NULL);
245b8e80941Smrg   }
246b8e80941Smrg
247b8e80941Smrg   switch (ir->operation) {
248b8e80941Smrg   case ir_unop_bit_not:
249b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
250b8e80941Smrg      break;
251b8e80941Smrg   case ir_unop_logic_not:
252b8e80941Smrg      assert(ir->type->is_boolean());
253b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
254b8e80941Smrg      break;
255b8e80941Smrg
256b8e80941Smrg   case ir_unop_neg:
257b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
258b8e80941Smrg      break;
259b8e80941Smrg
260b8e80941Smrg   case ir_unop_abs:
261b8e80941Smrg   case ir_unop_sign:
262b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT ||
263b8e80941Smrg             ir->operands[0]->type->is_float() ||
264b8e80941Smrg             ir->operands[0]->type->is_double() ||
265b8e80941Smrg             ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
266b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
267b8e80941Smrg      break;
268b8e80941Smrg
269b8e80941Smrg   case ir_unop_rcp:
270b8e80941Smrg   case ir_unop_rsq:
271b8e80941Smrg   case ir_unop_sqrt:
272b8e80941Smrg      assert(ir->type->is_float() ||
273b8e80941Smrg             ir->type->is_double());
274b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
275b8e80941Smrg      break;
276b8e80941Smrg
277b8e80941Smrg   case ir_unop_exp:
278b8e80941Smrg   case ir_unop_log:
279b8e80941Smrg   case ir_unop_exp2:
280b8e80941Smrg   case ir_unop_log2:
281b8e80941Smrg   case ir_unop_saturate:
282b8e80941Smrg      assert(ir->operands[0]->type->is_float());
283b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
284b8e80941Smrg      break;
285b8e80941Smrg
286b8e80941Smrg   case ir_unop_f2i:
287b8e80941Smrg      assert(ir->operands[0]->type->is_float());
288b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
289b8e80941Smrg      break;
290b8e80941Smrg   case ir_unop_f2u:
291b8e80941Smrg      assert(ir->operands[0]->type->is_float());
292b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
293b8e80941Smrg      break;
294b8e80941Smrg   case ir_unop_i2f:
295b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
296b8e80941Smrg      assert(ir->type->is_float());
297b8e80941Smrg      break;
298b8e80941Smrg   case ir_unop_f2b:
299b8e80941Smrg      assert(ir->operands[0]->type->is_float());
300b8e80941Smrg      assert(ir->type->is_boolean());
301b8e80941Smrg      break;
302b8e80941Smrg   case ir_unop_b2f:
303b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
304b8e80941Smrg      assert(ir->type->is_float());
305b8e80941Smrg      break;
306b8e80941Smrg   case ir_unop_i2b:
307b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
308b8e80941Smrg      assert(ir->type->is_boolean());
309b8e80941Smrg      break;
310b8e80941Smrg   case ir_unop_b2i:
311b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
312b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
313b8e80941Smrg      break;
314b8e80941Smrg   case ir_unop_u2f:
315b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
316b8e80941Smrg      assert(ir->type->is_float());
317b8e80941Smrg      break;
318b8e80941Smrg   case ir_unop_i2u:
319b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
320b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
321b8e80941Smrg      break;
322b8e80941Smrg   case ir_unop_u2i:
323b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
324b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
325b8e80941Smrg      break;
326b8e80941Smrg   case ir_unop_bitcast_i2f:
327b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
328b8e80941Smrg      assert(ir->type->is_float());
329b8e80941Smrg      break;
330b8e80941Smrg   case ir_unop_bitcast_f2i:
331b8e80941Smrg      assert(ir->operands[0]->type->is_float());
332b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
333b8e80941Smrg      break;
334b8e80941Smrg   case ir_unop_bitcast_u2f:
335b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
336b8e80941Smrg      assert(ir->type->is_float());
337b8e80941Smrg      break;
338b8e80941Smrg   case ir_unop_bitcast_f2u:
339b8e80941Smrg      assert(ir->operands[0]->type->is_float());
340b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
341b8e80941Smrg      break;
342b8e80941Smrg
343b8e80941Smrg   case ir_unop_bitcast_u642d:
344b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
345b8e80941Smrg      assert(ir->type->is_double());
346b8e80941Smrg      break;
347b8e80941Smrg   case ir_unop_bitcast_i642d:
348b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
349b8e80941Smrg      assert(ir->type->is_double());
350b8e80941Smrg      break;
351b8e80941Smrg   case ir_unop_bitcast_d2u64:
352b8e80941Smrg      assert(ir->operands[0]->type->is_double());
353b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
354b8e80941Smrg      break;
355b8e80941Smrg   case ir_unop_bitcast_d2i64:
356b8e80941Smrg      assert(ir->operands[0]->type->is_double());
357b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
358b8e80941Smrg      break;
359b8e80941Smrg   case ir_unop_i642i:
360b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
361b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
362b8e80941Smrg      break;
363b8e80941Smrg   case ir_unop_u642i:
364b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
365b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
366b8e80941Smrg      break;
367b8e80941Smrg   case ir_unop_i642u:
368b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
369b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
370b8e80941Smrg      break;
371b8e80941Smrg   case ir_unop_u642u:
372b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
373b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
374b8e80941Smrg      break;
375b8e80941Smrg   case ir_unop_i642b:
376b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
377b8e80941Smrg      assert(ir->type->is_boolean());
378b8e80941Smrg      break;
379b8e80941Smrg   case ir_unop_i642f:
380b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
381b8e80941Smrg      assert(ir->type->is_float());
382b8e80941Smrg      break;
383b8e80941Smrg   case ir_unop_u642f:
384b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
385b8e80941Smrg      assert(ir->type->is_float());
386b8e80941Smrg      break;
387b8e80941Smrg   case ir_unop_i642d:
388b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
389b8e80941Smrg      assert(ir->type->is_double());
390b8e80941Smrg      break;
391b8e80941Smrg   case ir_unop_u642d:
392b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
393b8e80941Smrg      assert(ir->type->is_double());
394b8e80941Smrg      break;
395b8e80941Smrg   case ir_unop_i2i64:
396b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
397b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
398b8e80941Smrg      break;
399b8e80941Smrg   case ir_unop_u2i64:
400b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
401b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
402b8e80941Smrg      break;
403b8e80941Smrg   case ir_unop_b2i64:
404b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
405b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
406b8e80941Smrg      break;
407b8e80941Smrg   case ir_unop_f2i64:
408b8e80941Smrg      assert(ir->operands[0]->type->is_float());
409b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
410b8e80941Smrg      break;
411b8e80941Smrg   case ir_unop_d2i64:
412b8e80941Smrg      assert(ir->operands[0]->type->is_double());
413b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
414b8e80941Smrg      break;
415b8e80941Smrg   case ir_unop_i2u64:
416b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
417b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
418b8e80941Smrg      break;
419b8e80941Smrg   case ir_unop_u2u64:
420b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
421b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
422b8e80941Smrg      break;
423b8e80941Smrg   case ir_unop_f2u64:
424b8e80941Smrg      assert(ir->operands[0]->type->is_float());
425b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
426b8e80941Smrg      break;
427b8e80941Smrg   case ir_unop_d2u64:
428b8e80941Smrg      assert(ir->operands[0]->type->is_double());
429b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
430b8e80941Smrg      break;
431b8e80941Smrg   case ir_unop_u642i64:
432b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
433b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT64);
434b8e80941Smrg      break;
435b8e80941Smrg   case ir_unop_i642u64:
436b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
437b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT64);
438b8e80941Smrg      break;
439b8e80941Smrg   case ir_unop_trunc:
440b8e80941Smrg   case ir_unop_round_even:
441b8e80941Smrg   case ir_unop_ceil:
442b8e80941Smrg   case ir_unop_floor:
443b8e80941Smrg   case ir_unop_fract:
444b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
445b8e80941Smrg             ir->operands[0]->type->is_double());
446b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
447b8e80941Smrg      break;
448b8e80941Smrg   case ir_unop_sin:
449b8e80941Smrg   case ir_unop_cos:
450b8e80941Smrg   case ir_unop_dFdx:
451b8e80941Smrg   case ir_unop_dFdx_coarse:
452b8e80941Smrg   case ir_unop_dFdx_fine:
453b8e80941Smrg   case ir_unop_dFdy:
454b8e80941Smrg   case ir_unop_dFdy_coarse:
455b8e80941Smrg   case ir_unop_dFdy_fine:
456b8e80941Smrg      assert(ir->operands[0]->type->is_float());
457b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
458b8e80941Smrg      break;
459b8e80941Smrg
460b8e80941Smrg   case ir_unop_pack_snorm_2x16:
461b8e80941Smrg   case ir_unop_pack_unorm_2x16:
462b8e80941Smrg   case ir_unop_pack_half_2x16:
463b8e80941Smrg      assert(ir->type == glsl_type::uint_type);
464b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::vec2_type);
465b8e80941Smrg      break;
466b8e80941Smrg
467b8e80941Smrg   case ir_unop_pack_snorm_4x8:
468b8e80941Smrg   case ir_unop_pack_unorm_4x8:
469b8e80941Smrg      assert(ir->type == glsl_type::uint_type);
470b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::vec4_type);
471b8e80941Smrg      break;
472b8e80941Smrg
473b8e80941Smrg   case ir_unop_pack_double_2x32:
474b8e80941Smrg      assert(ir->type == glsl_type::double_type);
475b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uvec2_type);
476b8e80941Smrg      break;
477b8e80941Smrg
478b8e80941Smrg   case ir_unop_pack_int_2x32:
479b8e80941Smrg      assert(ir->type == glsl_type::int64_t_type);
480b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::ivec2_type);
481b8e80941Smrg      break;
482b8e80941Smrg
483b8e80941Smrg   case ir_unop_pack_uint_2x32:
484b8e80941Smrg      assert(ir->type == glsl_type::uint64_t_type);
485b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uvec2_type);
486b8e80941Smrg      break;
487b8e80941Smrg
488b8e80941Smrg   case ir_unop_pack_sampler_2x32:
489b8e80941Smrg      assert(ir->type->is_sampler());
490b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uvec2_type);
491b8e80941Smrg      break;
492b8e80941Smrg
493b8e80941Smrg   case ir_unop_pack_image_2x32:
494b8e80941Smrg      assert(ir->type->is_image());
495b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uvec2_type);
496b8e80941Smrg      break;
497b8e80941Smrg
498b8e80941Smrg   case ir_unop_unpack_snorm_2x16:
499b8e80941Smrg   case ir_unop_unpack_unorm_2x16:
500b8e80941Smrg   case ir_unop_unpack_half_2x16:
501b8e80941Smrg      assert(ir->type == glsl_type::vec2_type);
502b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uint_type);
503b8e80941Smrg      break;
504b8e80941Smrg
505b8e80941Smrg   case ir_unop_unpack_snorm_4x8:
506b8e80941Smrg   case ir_unop_unpack_unorm_4x8:
507b8e80941Smrg      assert(ir->type == glsl_type::vec4_type);
508b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uint_type);
509b8e80941Smrg      break;
510b8e80941Smrg
511b8e80941Smrg   case ir_unop_unpack_double_2x32:
512b8e80941Smrg      assert(ir->type == glsl_type::uvec2_type);
513b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::double_type);
514b8e80941Smrg      break;
515b8e80941Smrg
516b8e80941Smrg   case ir_unop_unpack_int_2x32:
517b8e80941Smrg      assert(ir->type == glsl_type::ivec2_type);
518b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::int64_t_type);
519b8e80941Smrg      break;
520b8e80941Smrg
521b8e80941Smrg   case ir_unop_unpack_uint_2x32:
522b8e80941Smrg      assert(ir->type == glsl_type::uvec2_type);
523b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uint64_t_type);
524b8e80941Smrg      break;
525b8e80941Smrg
526b8e80941Smrg   case ir_unop_unpack_sampler_2x32:
527b8e80941Smrg      assert(ir->type == glsl_type::uvec2_type);
528b8e80941Smrg      assert(ir->operands[0]->type->is_sampler());
529b8e80941Smrg      break;
530b8e80941Smrg
531b8e80941Smrg   case ir_unop_unpack_image_2x32:
532b8e80941Smrg      assert(ir->type == glsl_type::uvec2_type);
533b8e80941Smrg      assert(ir->operands[0]->type->is_image());
534b8e80941Smrg      break;
535b8e80941Smrg
536b8e80941Smrg   case ir_unop_bitfield_reverse:
537b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
538b8e80941Smrg      assert(ir->type->is_integer());
539b8e80941Smrg      break;
540b8e80941Smrg
541b8e80941Smrg   case ir_unop_bit_count:
542b8e80941Smrg   case ir_unop_find_msb:
543b8e80941Smrg   case ir_unop_find_lsb:
544b8e80941Smrg      assert(ir->operands[0]->type->vector_elements == ir->type->vector_elements);
545b8e80941Smrg      assert(ir->operands[0]->type->is_integer());
546b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
547b8e80941Smrg      break;
548b8e80941Smrg
549b8e80941Smrg   case ir_unop_noise:
550b8e80941Smrg      /* XXX what can we assert here? */
551b8e80941Smrg      break;
552b8e80941Smrg
553b8e80941Smrg   case ir_unop_interpolate_at_centroid:
554b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
555b8e80941Smrg      assert(ir->operands[0]->type->is_float());
556b8e80941Smrg      break;
557b8e80941Smrg
558b8e80941Smrg   case ir_unop_get_buffer_size:
559b8e80941Smrg      assert(ir->type == glsl_type::int_type);
560b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uint_type);
561b8e80941Smrg      break;
562b8e80941Smrg
563b8e80941Smrg   case ir_unop_ssbo_unsized_array_length:
564b8e80941Smrg      assert(ir->type == glsl_type::int_type);
565b8e80941Smrg      assert(ir->operands[0]->type->is_array());
566b8e80941Smrg      assert(ir->operands[0]->type->is_unsized_array());
567b8e80941Smrg      break;
568b8e80941Smrg
569b8e80941Smrg   case ir_unop_d2f:
570b8e80941Smrg      assert(ir->operands[0]->type->is_double());
571b8e80941Smrg      assert(ir->type->is_float());
572b8e80941Smrg      break;
573b8e80941Smrg   case ir_unop_f2d:
574b8e80941Smrg      assert(ir->operands[0]->type->is_float());
575b8e80941Smrg      assert(ir->type->is_double());
576b8e80941Smrg      break;
577b8e80941Smrg   case ir_unop_d2i:
578b8e80941Smrg      assert(ir->operands[0]->type->is_double());
579b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
580b8e80941Smrg      break;
581b8e80941Smrg   case ir_unop_i2d:
582b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
583b8e80941Smrg      assert(ir->type->is_double());
584b8e80941Smrg      break;
585b8e80941Smrg   case ir_unop_d2u:
586b8e80941Smrg      assert(ir->operands[0]->type->is_double());
587b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
588b8e80941Smrg      break;
589b8e80941Smrg   case ir_unop_u2d:
590b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
591b8e80941Smrg      assert(ir->type->is_double());
592b8e80941Smrg      break;
593b8e80941Smrg   case ir_unop_d2b:
594b8e80941Smrg      assert(ir->operands[0]->type->is_double());
595b8e80941Smrg      assert(ir->type->is_boolean());
596b8e80941Smrg      break;
597b8e80941Smrg
598b8e80941Smrg   case ir_unop_frexp_sig:
599b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
600b8e80941Smrg             ir->operands[0]->type->is_double());
601b8e80941Smrg      assert(ir->type->is_double());
602b8e80941Smrg      break;
603b8e80941Smrg   case ir_unop_frexp_exp:
604b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
605b8e80941Smrg             ir->operands[0]->type->is_double());
606b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
607b8e80941Smrg      break;
608b8e80941Smrg   case ir_unop_subroutine_to_int:
609b8e80941Smrg      assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
610b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_INT);
611b8e80941Smrg      break;
612b8e80941Smrg
613b8e80941Smrg   case ir_binop_add:
614b8e80941Smrg   case ir_binop_sub:
615b8e80941Smrg   case ir_binop_mul:
616b8e80941Smrg   case ir_binop_div:
617b8e80941Smrg   case ir_binop_mod:
618b8e80941Smrg   case ir_binop_min:
619b8e80941Smrg   case ir_binop_max:
620b8e80941Smrg   case ir_binop_pow:
621b8e80941Smrg      assert(ir->operands[0]->type->base_type ==
622b8e80941Smrg             ir->operands[1]->type->base_type);
623b8e80941Smrg
624b8e80941Smrg      if (ir->operation == ir_binop_mul &&
625b8e80941Smrg          (ir->type->base_type == GLSL_TYPE_UINT64 ||
626b8e80941Smrg           ir->type->base_type == GLSL_TYPE_INT64) &&
627b8e80941Smrg          (ir->operands[0]->type->base_type == GLSL_TYPE_INT ||
628b8e80941Smrg           ir->operands[1]->type->base_type == GLSL_TYPE_INT ||
629b8e80941Smrg           ir->operands[0]->type->base_type == GLSL_TYPE_UINT ||
630b8e80941Smrg           ir->operands[1]->type->base_type == GLSL_TYPE_UINT)) {
631b8e80941Smrg         assert(ir->operands[0]->type == ir->operands[1]->type);
632b8e80941Smrg         break;
633b8e80941Smrg      }
634b8e80941Smrg
635b8e80941Smrg      if (ir->operands[0]->type->is_scalar())
636b8e80941Smrg	 assert(ir->operands[1]->type == ir->type);
637b8e80941Smrg      else if (ir->operands[1]->type->is_scalar())
638b8e80941Smrg	 assert(ir->operands[0]->type == ir->type);
639b8e80941Smrg      else if (ir->operands[0]->type->is_vector() &&
640b8e80941Smrg	       ir->operands[1]->type->is_vector()) {
641b8e80941Smrg	 assert(ir->operands[0]->type == ir->operands[1]->type);
642b8e80941Smrg	 assert(ir->operands[0]->type == ir->type);
643b8e80941Smrg      }
644b8e80941Smrg      break;
645b8e80941Smrg
646b8e80941Smrg   case ir_binop_imul_high:
647b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
648b8e80941Smrg      assert(ir->type == ir->operands[1]->type);
649b8e80941Smrg      assert(ir->type->is_integer());
650b8e80941Smrg      break;
651b8e80941Smrg
652b8e80941Smrg   case ir_binop_carry:
653b8e80941Smrg   case ir_binop_borrow:
654b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
655b8e80941Smrg      assert(ir->type == ir->operands[1]->type);
656b8e80941Smrg      assert(ir->type->base_type == GLSL_TYPE_UINT);
657b8e80941Smrg      break;
658b8e80941Smrg
659b8e80941Smrg   case ir_binop_less:
660b8e80941Smrg   case ir_binop_gequal:
661b8e80941Smrg   case ir_binop_equal:
662b8e80941Smrg   case ir_binop_nequal:
663b8e80941Smrg      /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
664b8e80941Smrg       * ==, and != operators.  The IR operators perform a component-wise
665b8e80941Smrg       * comparison on scalar or vector types and return a boolean scalar or
666b8e80941Smrg       * vector type of the same size.
667b8e80941Smrg       */
668b8e80941Smrg      assert(ir->type->is_boolean());
669b8e80941Smrg      assert(ir->operands[0]->type == ir->operands[1]->type);
670b8e80941Smrg      assert(ir->operands[0]->type->is_vector()
671b8e80941Smrg	     || ir->operands[0]->type->is_scalar());
672b8e80941Smrg      assert(ir->operands[0]->type->vector_elements
673b8e80941Smrg	     == ir->type->vector_elements);
674b8e80941Smrg      break;
675b8e80941Smrg
676b8e80941Smrg   case ir_binop_all_equal:
677b8e80941Smrg   case ir_binop_any_nequal:
678b8e80941Smrg      /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
679b8e80941Smrg       * return a scalar boolean.  The IR matches that.
680b8e80941Smrg       */
681b8e80941Smrg      assert(ir->type == glsl_type::bool_type);
682b8e80941Smrg      assert(ir->operands[0]->type == ir->operands[1]->type);
683b8e80941Smrg      break;
684b8e80941Smrg
685b8e80941Smrg   case ir_binop_lshift:
686b8e80941Smrg   case ir_binop_rshift:
687b8e80941Smrg      assert(ir->operands[0]->type->is_integer_32_64() &&
688b8e80941Smrg             ir->operands[1]->type->is_integer());
689b8e80941Smrg      if (ir->operands[0]->type->is_scalar()) {
690b8e80941Smrg          assert(ir->operands[1]->type->is_scalar());
691b8e80941Smrg      }
692b8e80941Smrg      if (ir->operands[0]->type->is_vector() &&
693b8e80941Smrg          ir->operands[1]->type->is_vector()) {
694b8e80941Smrg          assert(ir->operands[0]->type->components() ==
695b8e80941Smrg                 ir->operands[1]->type->components());
696b8e80941Smrg      }
697b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
698b8e80941Smrg      break;
699b8e80941Smrg
700b8e80941Smrg   case ir_binop_bit_and:
701b8e80941Smrg   case ir_binop_bit_xor:
702b8e80941Smrg   case ir_binop_bit_or:
703b8e80941Smrg       assert(ir->operands[0]->type->base_type ==
704b8e80941Smrg              ir->operands[1]->type->base_type);
705b8e80941Smrg       assert(ir->type->is_integer_32_64());
706b8e80941Smrg       if (ir->operands[0]->type->is_vector() &&
707b8e80941Smrg           ir->operands[1]->type->is_vector()) {
708b8e80941Smrg           assert(ir->operands[0]->type->vector_elements ==
709b8e80941Smrg                  ir->operands[1]->type->vector_elements);
710b8e80941Smrg       }
711b8e80941Smrg       break;
712b8e80941Smrg
713b8e80941Smrg   case ir_binop_logic_and:
714b8e80941Smrg   case ir_binop_logic_xor:
715b8e80941Smrg   case ir_binop_logic_or:
716b8e80941Smrg      assert(ir->type->is_boolean());
717b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
718b8e80941Smrg      assert(ir->operands[1]->type->is_boolean());
719b8e80941Smrg      break;
720b8e80941Smrg
721b8e80941Smrg   case ir_binop_dot:
722b8e80941Smrg      assert(ir->type == glsl_type::float_type ||
723b8e80941Smrg             ir->type == glsl_type::double_type);
724b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
725b8e80941Smrg             ir->operands[0]->type->is_double());
726b8e80941Smrg      assert(ir->operands[0]->type->is_vector());
727b8e80941Smrg      assert(ir->operands[0]->type == ir->operands[1]->type);
728b8e80941Smrg      break;
729b8e80941Smrg
730b8e80941Smrg   case ir_binop_ubo_load:
731b8e80941Smrg      assert(ir->operands[0]->type == glsl_type::uint_type);
732b8e80941Smrg
733b8e80941Smrg      assert(ir->operands[1]->type == glsl_type::uint_type);
734b8e80941Smrg      break;
735b8e80941Smrg
736b8e80941Smrg   case ir_binop_ldexp:
737b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
738b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
739b8e80941Smrg             ir->operands[0]->type->is_double());
740b8e80941Smrg      assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT);
741b8e80941Smrg      assert(ir->operands[0]->type->components() ==
742b8e80941Smrg             ir->operands[1]->type->components());
743b8e80941Smrg      break;
744b8e80941Smrg
745b8e80941Smrg   case ir_binop_vector_extract:
746b8e80941Smrg      assert(ir->operands[0]->type->is_vector());
747b8e80941Smrg      assert(ir->operands[1]->type->is_scalar()
748b8e80941Smrg             && ir->operands[1]->type->is_integer());
749b8e80941Smrg      break;
750b8e80941Smrg
751b8e80941Smrg   case ir_binop_interpolate_at_offset:
752b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
753b8e80941Smrg      assert(ir->operands[0]->type->is_float());
754b8e80941Smrg      assert(ir->operands[1]->type->components() == 2);
755b8e80941Smrg      assert(ir->operands[1]->type->is_float());
756b8e80941Smrg      break;
757b8e80941Smrg
758b8e80941Smrg   case ir_binop_interpolate_at_sample:
759b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
760b8e80941Smrg      assert(ir->operands[0]->type->is_float());
761b8e80941Smrg      assert(ir->operands[1]->type == glsl_type::int_type);
762b8e80941Smrg      break;
763b8e80941Smrg
764b8e80941Smrg   case ir_triop_fma:
765b8e80941Smrg      assert(ir->type->is_float() ||
766b8e80941Smrg             ir->type->is_double());
767b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
768b8e80941Smrg      assert(ir->type == ir->operands[1]->type);
769b8e80941Smrg      assert(ir->type == ir->operands[2]->type);
770b8e80941Smrg      break;
771b8e80941Smrg
772b8e80941Smrg   case ir_triop_lrp:
773b8e80941Smrg      assert(ir->operands[0]->type->is_float() ||
774b8e80941Smrg             ir->operands[0]->type->is_double());
775b8e80941Smrg      assert(ir->operands[0]->type == ir->operands[1]->type);
776b8e80941Smrg      assert(ir->operands[2]->type == ir->operands[0]->type ||
777b8e80941Smrg             ir->operands[2]->type == glsl_type::float_type ||
778b8e80941Smrg             ir->operands[2]->type == glsl_type::double_type);
779b8e80941Smrg      break;
780b8e80941Smrg
781b8e80941Smrg   case ir_triop_csel:
782b8e80941Smrg      assert(ir->operands[0]->type->is_boolean());
783b8e80941Smrg      assert(ir->type->vector_elements == ir->operands[0]->type->vector_elements);
784b8e80941Smrg      assert(ir->type == ir->operands[1]->type);
785b8e80941Smrg      assert(ir->type == ir->operands[2]->type);
786b8e80941Smrg      break;
787b8e80941Smrg
788b8e80941Smrg   case ir_triop_bitfield_extract:
789b8e80941Smrg      assert(ir->type->is_integer());
790b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
791b8e80941Smrg      assert(ir->operands[1]->type == ir->type);
792b8e80941Smrg      assert(ir->operands[2]->type == ir->type);
793b8e80941Smrg      break;
794b8e80941Smrg
795b8e80941Smrg   case ir_triop_vector_insert:
796b8e80941Smrg      assert(ir->operands[0]->type->is_vector());
797b8e80941Smrg      assert(ir->operands[1]->type->is_scalar());
798b8e80941Smrg      assert(ir->operands[0]->type->base_type == ir->operands[1]->type->base_type);
799b8e80941Smrg      assert(ir->operands[2]->type->is_scalar()
800b8e80941Smrg             && ir->operands[2]->type->is_integer());
801b8e80941Smrg      assert(ir->type == ir->operands[0]->type);
802b8e80941Smrg      break;
803b8e80941Smrg
804b8e80941Smrg   case ir_quadop_bitfield_insert:
805b8e80941Smrg      assert(ir->type->is_integer());
806b8e80941Smrg      assert(ir->operands[0]->type == ir->type);
807b8e80941Smrg      assert(ir->operands[1]->type == ir->type);
808b8e80941Smrg      assert(ir->operands[2]->type == ir->type);
809b8e80941Smrg      assert(ir->operands[3]->type == ir->type);
810b8e80941Smrg      break;
811b8e80941Smrg
812b8e80941Smrg   case ir_quadop_vector:
813b8e80941Smrg      /* The vector operator collects some number of scalars and generates a
814b8e80941Smrg       * vector from them.
815b8e80941Smrg       *
816b8e80941Smrg       *  - All of the operands must be scalar.
817b8e80941Smrg       *  - Number of operands must matche the size of the resulting vector.
818b8e80941Smrg       *  - Base type of the operands must match the base type of the result.
819b8e80941Smrg       */
820b8e80941Smrg      assert(ir->type->is_vector());
821b8e80941Smrg      switch (ir->type->vector_elements) {
822b8e80941Smrg      case 2:
823b8e80941Smrg	 assert(ir->operands[0]->type->is_scalar());
824b8e80941Smrg	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
825b8e80941Smrg	 assert(ir->operands[1]->type->is_scalar());
826b8e80941Smrg	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
827b8e80941Smrg	 assert(ir->operands[2] == NULL);
828b8e80941Smrg	 assert(ir->operands[3] == NULL);
829b8e80941Smrg	 break;
830b8e80941Smrg      case 3:
831b8e80941Smrg	 assert(ir->operands[0]->type->is_scalar());
832b8e80941Smrg	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
833b8e80941Smrg	 assert(ir->operands[1]->type->is_scalar());
834b8e80941Smrg	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
835b8e80941Smrg	 assert(ir->operands[2]->type->is_scalar());
836b8e80941Smrg	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
837b8e80941Smrg	 assert(ir->operands[3] == NULL);
838b8e80941Smrg	 break;
839b8e80941Smrg      case 4:
840b8e80941Smrg	 assert(ir->operands[0]->type->is_scalar());
841b8e80941Smrg	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
842b8e80941Smrg	 assert(ir->operands[1]->type->is_scalar());
843b8e80941Smrg	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
844b8e80941Smrg	 assert(ir->operands[2]->type->is_scalar());
845b8e80941Smrg	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
846b8e80941Smrg	 assert(ir->operands[3]->type->is_scalar());
847b8e80941Smrg	 assert(ir->operands[3]->type->base_type == ir->type->base_type);
848b8e80941Smrg	 break;
849b8e80941Smrg      default:
850b8e80941Smrg	 /* The is_vector assertion above should prevent execution from ever
851b8e80941Smrg	  * getting here.
852b8e80941Smrg	  */
853b8e80941Smrg	 assert(!"Should not get here.");
854b8e80941Smrg	 break;
855b8e80941Smrg      }
856b8e80941Smrg   }
857b8e80941Smrg
858b8e80941Smrg   return visit_continue;
859b8e80941Smrg}
860b8e80941Smrg
861b8e80941Smrgir_visitor_status
862b8e80941Smrgir_validate::visit_leave(ir_swizzle *ir)
863b8e80941Smrg{
864b8e80941Smrg   unsigned int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
865b8e80941Smrg
866b8e80941Smrg   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
867b8e80941Smrg      if (chans[i] >= ir->val->type->vector_elements) {
868b8e80941Smrg	 printf("ir_swizzle @ %p specifies a channel not present "
869b8e80941Smrg		"in the value.\n", (void *) ir);
870b8e80941Smrg	 ir->print();
871b8e80941Smrg	 abort();
872b8e80941Smrg      }
873b8e80941Smrg   }
874b8e80941Smrg
875b8e80941Smrg   return visit_continue;
876b8e80941Smrg}
877b8e80941Smrg
878b8e80941Smrgir_visitor_status
879b8e80941Smrgir_validate::visit(ir_variable *ir)
880b8e80941Smrg{
881b8e80941Smrg   /* An ir_variable is the one thing that can (and will) appear multiple times
882b8e80941Smrg    * in an IR tree.  It is added to the hashtable so that it can be used
883b8e80941Smrg    * in the ir_dereference_variable handler to ensure that a variable is
884b8e80941Smrg    * declared before it is dereferenced.
885b8e80941Smrg    */
886b8e80941Smrg   if (ir->name && ir->is_name_ralloced())
887b8e80941Smrg      assert(ralloc_parent(ir->name) == ir);
888b8e80941Smrg
889b8e80941Smrg   _mesa_set_add(ir_set, ir);
890b8e80941Smrg
891b8e80941Smrg   /* If a variable is an array, verify that the maximum array index is in
892b8e80941Smrg    * bounds.  There was once an error in AST-to-HIR conversion that set this
893b8e80941Smrg    * to be out of bounds.
894b8e80941Smrg    */
895b8e80941Smrg   if (ir->type->array_size() > 0) {
896b8e80941Smrg      if (ir->data.max_array_access >= (int)ir->type->length) {
897b8e80941Smrg	 printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
898b8e80941Smrg		ir->data.max_array_access, ir->type->length - 1);
899b8e80941Smrg	 ir->print();
900b8e80941Smrg	 abort();
901b8e80941Smrg      }
902b8e80941Smrg   }
903b8e80941Smrg
904b8e80941Smrg   /* If a variable is an interface block (or an array of interface blocks),
905b8e80941Smrg    * verify that the maximum array index for each interface member is in
906b8e80941Smrg    * bounds.
907b8e80941Smrg    */
908b8e80941Smrg   if (ir->is_interface_instance()) {
909b8e80941Smrg      const glsl_struct_field *fields =
910b8e80941Smrg         ir->get_interface_type()->fields.structure;
911b8e80941Smrg      for (unsigned i = 0; i < ir->get_interface_type()->length; i++) {
912b8e80941Smrg         if (fields[i].type->array_size() > 0 &&
913b8e80941Smrg             !fields[i].implicit_sized_array) {
914b8e80941Smrg            const int *const max_ifc_array_access =
915b8e80941Smrg               ir->get_max_ifc_array_access();
916b8e80941Smrg
917b8e80941Smrg            assert(max_ifc_array_access != NULL);
918b8e80941Smrg
919b8e80941Smrg            if (max_ifc_array_access[i] >= (int)fields[i].type->length) {
920b8e80941Smrg               printf("ir_variable has maximum access out of bounds for "
921b8e80941Smrg                      "field %s (%d vs %d)\n", fields[i].name,
922b8e80941Smrg                      max_ifc_array_access[i], fields[i].type->length);
923b8e80941Smrg               ir->print();
924b8e80941Smrg               abort();
925b8e80941Smrg            }
926b8e80941Smrg         }
927b8e80941Smrg      }
928b8e80941Smrg   }
929b8e80941Smrg
930b8e80941Smrg   if (ir->constant_initializer != NULL && !ir->data.has_initializer) {
931b8e80941Smrg      printf("ir_variable didn't have an initializer, but has a constant "
932b8e80941Smrg	     "initializer value.\n");
933b8e80941Smrg      ir->print();
934b8e80941Smrg      abort();
935b8e80941Smrg   }
936b8e80941Smrg
937b8e80941Smrg   if (ir->data.mode == ir_var_uniform
938b8e80941Smrg       && is_gl_identifier(ir->name)
939b8e80941Smrg       && ir->get_state_slots() == NULL) {
940b8e80941Smrg      printf("built-in uniform has no state\n");
941b8e80941Smrg      ir->print();
942b8e80941Smrg      abort();
943b8e80941Smrg   }
944b8e80941Smrg
945b8e80941Smrg   return visit_continue;
946b8e80941Smrg}
947b8e80941Smrg
948b8e80941Smrgir_visitor_status
949b8e80941Smrgir_validate::visit_enter(ir_assignment *ir)
950b8e80941Smrg{
951b8e80941Smrg   const ir_dereference *const lhs = ir->lhs;
952b8e80941Smrg   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
953b8e80941Smrg      if (ir->write_mask == 0) {
954b8e80941Smrg	 printf("Assignment LHS is %s, but write mask is 0:\n",
955b8e80941Smrg		lhs->type->is_scalar() ? "scalar" : "vector");
956b8e80941Smrg	 ir->print();
957b8e80941Smrg	 abort();
958b8e80941Smrg      }
959b8e80941Smrg
960b8e80941Smrg      int lhs_components = 0;
961b8e80941Smrg      for (int i = 0; i < 4; i++) {
962b8e80941Smrg	 if (ir->write_mask & (1 << i))
963b8e80941Smrg	    lhs_components++;
964b8e80941Smrg      }
965b8e80941Smrg
966b8e80941Smrg      if (lhs_components != ir->rhs->type->vector_elements) {
967b8e80941Smrg	 printf("Assignment count of LHS write mask channels enabled not\n"
968b8e80941Smrg		"matching RHS vector size (%d LHS, %d RHS).\n",
969b8e80941Smrg		lhs_components, ir->rhs->type->vector_elements);
970b8e80941Smrg	 ir->print();
971b8e80941Smrg	 abort();
972b8e80941Smrg      }
973b8e80941Smrg   }
974b8e80941Smrg
975b8e80941Smrg   this->validate_ir(ir, this->data_enter);
976b8e80941Smrg
977b8e80941Smrg   return visit_continue;
978b8e80941Smrg}
979b8e80941Smrg
980b8e80941Smrgir_visitor_status
981b8e80941Smrgir_validate::visit_enter(ir_call *ir)
982b8e80941Smrg{
983b8e80941Smrg   ir_function_signature *const callee = ir->callee;
984b8e80941Smrg
985b8e80941Smrg   if (callee->ir_type != ir_type_function_signature) {
986b8e80941Smrg      printf("IR called by ir_call is not ir_function_signature!\n");
987b8e80941Smrg      abort();
988b8e80941Smrg   }
989b8e80941Smrg
990b8e80941Smrg   if (ir->return_deref) {
991b8e80941Smrg      if (ir->return_deref->type != callee->return_type) {
992b8e80941Smrg	 printf("callee type %s does not match return storage type %s\n",
993b8e80941Smrg	        callee->return_type->name, ir->return_deref->type->name);
994b8e80941Smrg	 abort();
995b8e80941Smrg      }
996b8e80941Smrg   } else if (callee->return_type != glsl_type::void_type) {
997b8e80941Smrg      printf("ir_call has non-void callee but no return storage\n");
998b8e80941Smrg      abort();
999b8e80941Smrg   }
1000b8e80941Smrg
1001b8e80941Smrg   const exec_node *formal_param_node = callee->parameters.get_head_raw();
1002b8e80941Smrg   const exec_node *actual_param_node = ir->actual_parameters.get_head_raw();
1003b8e80941Smrg   while (true) {
1004b8e80941Smrg      if (formal_param_node->is_tail_sentinel()
1005b8e80941Smrg          != actual_param_node->is_tail_sentinel()) {
1006b8e80941Smrg         printf("ir_call has the wrong number of parameters:\n");
1007b8e80941Smrg         goto dump_ir;
1008b8e80941Smrg      }
1009b8e80941Smrg      if (formal_param_node->is_tail_sentinel()) {
1010b8e80941Smrg         break;
1011b8e80941Smrg      }
1012b8e80941Smrg      const ir_variable *formal_param
1013b8e80941Smrg         = (const ir_variable *) formal_param_node;
1014b8e80941Smrg      const ir_rvalue *actual_param
1015b8e80941Smrg         = (const ir_rvalue *) actual_param_node;
1016b8e80941Smrg      if (formal_param->type != actual_param->type) {
1017b8e80941Smrg         printf("ir_call parameter type mismatch:\n");
1018b8e80941Smrg         goto dump_ir;
1019b8e80941Smrg      }
1020b8e80941Smrg      if (formal_param->data.mode == ir_var_function_out
1021b8e80941Smrg          || formal_param->data.mode == ir_var_function_inout) {
1022b8e80941Smrg         if (!actual_param->is_lvalue()) {
1023b8e80941Smrg            printf("ir_call out/inout parameters must be lvalues:\n");
1024b8e80941Smrg            goto dump_ir;
1025b8e80941Smrg         }
1026b8e80941Smrg      }
1027b8e80941Smrg      formal_param_node = formal_param_node->next;
1028b8e80941Smrg      actual_param_node = actual_param_node->next;
1029b8e80941Smrg   }
1030b8e80941Smrg
1031b8e80941Smrg   return visit_continue;
1032b8e80941Smrg
1033b8e80941Smrgdump_ir:
1034b8e80941Smrg   ir->print();
1035b8e80941Smrg   printf("callee:\n");
1036b8e80941Smrg   callee->print();
1037b8e80941Smrg   abort();
1038b8e80941Smrg   return visit_stop;
1039b8e80941Smrg}
1040b8e80941Smrg
1041b8e80941Smrgvoid
1042b8e80941Smrgir_validate::validate_ir(ir_instruction *ir, void *data)
1043b8e80941Smrg{
1044b8e80941Smrg   struct set *ir_set = (struct set *) data;
1045b8e80941Smrg
1046b8e80941Smrg   if (_mesa_set_search(ir_set, ir)) {
1047b8e80941Smrg      printf("Instruction node present twice in ir tree:\n");
1048b8e80941Smrg      ir->print();
1049b8e80941Smrg      printf("\n");
1050b8e80941Smrg      abort();
1051b8e80941Smrg   }
1052b8e80941Smrg   _mesa_set_add(ir_set, ir);
1053b8e80941Smrg}
1054b8e80941Smrg
1055b8e80941SmrgMAYBE_UNUSED static void
1056b8e80941Smrgcheck_node_type(ir_instruction *ir, void *data)
1057b8e80941Smrg{
1058b8e80941Smrg   (void) data;
1059b8e80941Smrg
1060b8e80941Smrg   if (ir->ir_type >= ir_type_max) {
1061b8e80941Smrg      printf("Instruction node with unset type\n");
1062b8e80941Smrg      ir->print(); printf("\n");
1063b8e80941Smrg   }
1064b8e80941Smrg   ir_rvalue *value = ir->as_rvalue();
1065b8e80941Smrg   if (value != NULL)
1066b8e80941Smrg      assert(value->type != glsl_type::error_type);
1067b8e80941Smrg}
1068b8e80941Smrg
1069b8e80941Smrgvoid
1070b8e80941Smrgvalidate_ir_tree(exec_list *instructions)
1071b8e80941Smrg{
1072b8e80941Smrg   /* We shouldn't have any reason to validate IR in a release build,
1073b8e80941Smrg    * and it's half composed of assert()s anyway which wouldn't do
1074b8e80941Smrg    * anything.
1075b8e80941Smrg    */
1076b8e80941Smrg#ifdef DEBUG
1077b8e80941Smrg   ir_validate v;
1078b8e80941Smrg
1079b8e80941Smrg   v.run(instructions);
1080b8e80941Smrg
1081b8e80941Smrg   foreach_in_list(ir_instruction, ir, instructions) {
1082b8e80941Smrg      visit_tree(ir, check_node_type, NULL);
1083b8e80941Smrg   }
1084b8e80941Smrg#endif
1085b8e80941Smrg}
1086