xref: /aosp_15_r20/external/mesa3d/src/compiler/glsl/ir_validate.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker /**
25*61046927SAndroid Build Coastguard Worker  * \file ir_validate.cpp
26*61046927SAndroid Build Coastguard Worker  *
27*61046927SAndroid Build Coastguard Worker  * Attempts to verify that various invariants of the IR tree are true.
28*61046927SAndroid Build Coastguard Worker  *
29*61046927SAndroid Build Coastguard Worker  * In particular, at the moment it makes sure that no single
30*61046927SAndroid Build Coastguard Worker  * ir_instruction node except for ir_variable appears multiple times
31*61046927SAndroid Build Coastguard Worker  * in the ir tree.  ir_variable does appear multiple times: Once as a
32*61046927SAndroid Build Coastguard Worker  * declaration in an exec_list, and multiple times as the endpoint of
33*61046927SAndroid Build Coastguard Worker  * a dereference chain.
34*61046927SAndroid Build Coastguard Worker  */
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker #include "ir.h"
37*61046927SAndroid Build Coastguard Worker #include "ir_hierarchical_visitor.h"
38*61046927SAndroid Build Coastguard Worker #include "linker_util.h"
39*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
40*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
41*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
42*61046927SAndroid Build Coastguard Worker #include "util/set.h"
43*61046927SAndroid Build Coastguard Worker #include "compiler/glsl_types.h"
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker namespace {
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker class ir_validate : public ir_hierarchical_visitor {
48*61046927SAndroid Build Coastguard Worker public:
ir_validate()49*61046927SAndroid Build Coastguard Worker    ir_validate()
50*61046927SAndroid Build Coastguard Worker    {
51*61046927SAndroid Build Coastguard Worker       this->ir_set = _mesa_pointer_set_create(NULL);
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker       this->current_function = NULL;
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker       this->callback_enter = ir_validate::validate_ir;
56*61046927SAndroid Build Coastguard Worker       this->data_enter = ir_set;
57*61046927SAndroid Build Coastguard Worker    }
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker    ir_validate(const ir_validate &) = delete;
60*61046927SAndroid Build Coastguard Worker    ir_validate & operator=(const ir_validate &) = delete;
61*61046927SAndroid Build Coastguard Worker 
~ir_validate()62*61046927SAndroid Build Coastguard Worker    ~ir_validate()
63*61046927SAndroid Build Coastguard Worker    {
64*61046927SAndroid Build Coastguard Worker       _mesa_set_destroy(this->ir_set, NULL);
65*61046927SAndroid Build Coastguard Worker    }
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit(ir_variable *v);
68*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit(ir_dereference_variable *ir);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_discard *ir);
71*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_if *ir);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_function *ir);
74*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_leave(ir_function *ir);
75*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_function_signature *ir);
76*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_return *ir);
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_leave(ir_expression *ir);
79*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_leave(ir_swizzle *ir);
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(class ir_dereference_array *);
82*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(class ir_dereference_record *);
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_assignment *ir);
85*61046927SAndroid Build Coastguard Worker    virtual ir_visitor_status visit_enter(ir_call *ir);
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    static void validate_ir(ir_instruction *ir, void *data);
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker    ir_function *current_function;
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    struct set *ir_set;
92*61046927SAndroid Build Coastguard Worker };
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker } /* anonymous namespace */
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit(ir_dereference_variable * ir)97*61046927SAndroid Build Coastguard Worker ir_validate::visit(ir_dereference_variable *ir)
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker    if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
100*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_variable @ %p does not specify a variable %p\n",
101*61046927SAndroid Build Coastguard Worker 	     (void *) ir, (void *) ir->var);
102*61046927SAndroid Build Coastguard Worker       abort();
103*61046927SAndroid Build Coastguard Worker    }
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    /* Compare types without arrays, because one side can be sized and
106*61046927SAndroid Build Coastguard Worker     * the other unsized.
107*61046927SAndroid Build Coastguard Worker     */
108*61046927SAndroid Build Coastguard Worker    if (glsl_without_array(ir->var->type) != glsl_without_array(ir->type)) {
109*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_variable type is not equal to variable type: ");
110*61046927SAndroid Build Coastguard Worker       ir->print();
111*61046927SAndroid Build Coastguard Worker       printf("\n");
112*61046927SAndroid Build Coastguard Worker       abort();
113*61046927SAndroid Build Coastguard Worker    }
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker    if (_mesa_set_search(ir_set, ir->var) == NULL) {
116*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_variable @ %p specifies undeclared variable "
117*61046927SAndroid Build Coastguard Worker 	     "`%s' @ %p\n",
118*61046927SAndroid Build Coastguard Worker 	     (void *) ir, ir->var->name, (void *) ir->var);
119*61046927SAndroid Build Coastguard Worker       abort();
120*61046927SAndroid Build Coastguard Worker    }
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker    this->validate_ir(ir, this->data_enter);
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    return visit_continue;
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(class ir_dereference_array * ir)128*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(class ir_dereference_array *ir)
129*61046927SAndroid Build Coastguard Worker {
130*61046927SAndroid Build Coastguard Worker    if (!glsl_type_is_array(ir->array->type) && !glsl_type_is_matrix(ir->array->type) &&
131*61046927SAndroid Build Coastguard Worker       !glsl_type_is_vector(ir->array->type)) {
132*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_array @ %p does not specify an array, a vector "
133*61046927SAndroid Build Coastguard Worker              "or a matrix\n",
134*61046927SAndroid Build Coastguard Worker              (void *) ir);
135*61046927SAndroid Build Coastguard Worker       ir->print();
136*61046927SAndroid Build Coastguard Worker       printf("\n");
137*61046927SAndroid Build Coastguard Worker       abort();
138*61046927SAndroid Build Coastguard Worker    }
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker    if (glsl_type_is_array(ir->array->type)) {
141*61046927SAndroid Build Coastguard Worker       if (ir->array->type->fields.array != ir->type) {
142*61046927SAndroid Build Coastguard Worker          printf("ir_dereference_array type is not equal to the array "
143*61046927SAndroid Build Coastguard Worker                 "element type: ");
144*61046927SAndroid Build Coastguard Worker          ir->print();
145*61046927SAndroid Build Coastguard Worker          printf("\n");
146*61046927SAndroid Build Coastguard Worker          abort();
147*61046927SAndroid Build Coastguard Worker       }
148*61046927SAndroid Build Coastguard Worker    } else if (ir->array->type->base_type != ir->type->base_type) {
149*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_array base types are not equal: ");
150*61046927SAndroid Build Coastguard Worker       ir->print();
151*61046927SAndroid Build Coastguard Worker       printf("\n");
152*61046927SAndroid Build Coastguard Worker       abort();
153*61046927SAndroid Build Coastguard Worker    }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    if (!glsl_type_is_scalar(ir->array_index->type)) {
156*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_array @ %p does not have scalar index: %s\n",
157*61046927SAndroid Build Coastguard Worker              (void *) ir, glsl_get_type_name(ir->array_index->type));
158*61046927SAndroid Build Coastguard Worker       abort();
159*61046927SAndroid Build Coastguard Worker    }
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker    if (!glsl_type_is_integer_16_32(ir->array_index->type)) {
162*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_array @ %p does not have integer index: %s\n",
163*61046927SAndroid Build Coastguard Worker              (void *) ir, glsl_get_type_name(ir->array_index->type));
164*61046927SAndroid Build Coastguard Worker       abort();
165*61046927SAndroid Build Coastguard Worker    }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker    return visit_continue;
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(class ir_dereference_record * ir)171*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(class ir_dereference_record *ir)
172*61046927SAndroid Build Coastguard Worker {
173*61046927SAndroid Build Coastguard Worker    if (!glsl_type_is_struct(ir->record->type) && !glsl_type_is_interface(ir->record->type)) {
174*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_record @ %p does not specify a record\n",
175*61046927SAndroid Build Coastguard Worker              (void *) ir);
176*61046927SAndroid Build Coastguard Worker       ir->print();
177*61046927SAndroid Build Coastguard Worker       printf("\n");
178*61046927SAndroid Build Coastguard Worker       abort();
179*61046927SAndroid Build Coastguard Worker    }
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    if (ir->record->type->fields.structure[ir->field_idx].type != ir->type) {
182*61046927SAndroid Build Coastguard Worker       printf("ir_dereference_record type is not equal to the record "
183*61046927SAndroid Build Coastguard Worker              "field type: ");
184*61046927SAndroid Build Coastguard Worker       ir->print();
185*61046927SAndroid Build Coastguard Worker       printf("\n");
186*61046927SAndroid Build Coastguard Worker       abort();
187*61046927SAndroid Build Coastguard Worker    }
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    return visit_continue;
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_discard * ir)193*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_discard *ir)
194*61046927SAndroid Build Coastguard Worker {
195*61046927SAndroid Build Coastguard Worker    if (ir->condition && ir->condition->type != &glsl_type_builtin_bool) {
196*61046927SAndroid Build Coastguard Worker       printf("ir_discard condition %s type instead of bool.\n",
197*61046927SAndroid Build Coastguard Worker 	     glsl_get_type_name(ir->condition->type));
198*61046927SAndroid Build Coastguard Worker       ir->print();
199*61046927SAndroid Build Coastguard Worker       printf("\n");
200*61046927SAndroid Build Coastguard Worker       abort();
201*61046927SAndroid Build Coastguard Worker    }
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker    return visit_continue;
204*61046927SAndroid Build Coastguard Worker }
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_if * ir)207*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_if *ir)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker    if (ir->condition->type != &glsl_type_builtin_bool) {
210*61046927SAndroid Build Coastguard Worker       printf("ir_if condition %s type instead of bool.\n",
211*61046927SAndroid Build Coastguard Worker 	     glsl_get_type_name(ir->condition->type));
212*61046927SAndroid Build Coastguard Worker       ir->print();
213*61046927SAndroid Build Coastguard Worker       printf("\n");
214*61046927SAndroid Build Coastguard Worker       abort();
215*61046927SAndroid Build Coastguard Worker    }
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker    return visit_continue;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_function * ir)222*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_function *ir)
223*61046927SAndroid Build Coastguard Worker {
224*61046927SAndroid Build Coastguard Worker    /* Function definitions cannot be nested.
225*61046927SAndroid Build Coastguard Worker     */
226*61046927SAndroid Build Coastguard Worker    if (this->current_function != NULL) {
227*61046927SAndroid Build Coastguard Worker       printf("Function definition nested inside another function "
228*61046927SAndroid Build Coastguard Worker 	     "definition:\n");
229*61046927SAndroid Build Coastguard Worker       printf("%s %p inside %s %p\n",
230*61046927SAndroid Build Coastguard Worker 	     ir->name, (void *) ir,
231*61046927SAndroid Build Coastguard Worker 	     this->current_function->name, (void *) this->current_function);
232*61046927SAndroid Build Coastguard Worker       abort();
233*61046927SAndroid Build Coastguard Worker    }
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    /* Store the current function hierarchy being traversed.  This is used
236*61046927SAndroid Build Coastguard Worker     * by the function signature visitor to ensure that the signatures are
237*61046927SAndroid Build Coastguard Worker     * linked with the correct functions.
238*61046927SAndroid Build Coastguard Worker     */
239*61046927SAndroid Build Coastguard Worker    this->current_function = ir;
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker    this->validate_ir(ir, this->data_enter);
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker    /* Verify that all of the things stored in the list of signatures are,
244*61046927SAndroid Build Coastguard Worker     * in fact, function signatures.
245*61046927SAndroid Build Coastguard Worker     */
246*61046927SAndroid Build Coastguard Worker    foreach_in_list(ir_instruction, sig, &ir->signatures) {
247*61046927SAndroid Build Coastguard Worker       if (sig->ir_type != ir_type_function_signature) {
248*61046927SAndroid Build Coastguard Worker 	 printf("Non-signature in signature list of function `%s'\n",
249*61046927SAndroid Build Coastguard Worker 		ir->name);
250*61046927SAndroid Build Coastguard Worker 	 abort();
251*61046927SAndroid Build Coastguard Worker       }
252*61046927SAndroid Build Coastguard Worker    }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker    return visit_continue;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_leave(ir_function * ir)258*61046927SAndroid Build Coastguard Worker ir_validate::visit_leave(ir_function *ir)
259*61046927SAndroid Build Coastguard Worker {
260*61046927SAndroid Build Coastguard Worker    assert(ralloc_parent(ir->name) == ir);
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker    this->current_function = NULL;
263*61046927SAndroid Build Coastguard Worker    return visit_continue;
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_function_signature * ir)267*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_function_signature *ir)
268*61046927SAndroid Build Coastguard Worker {
269*61046927SAndroid Build Coastguard Worker    if (this->current_function != ir->function()) {
270*61046927SAndroid Build Coastguard Worker       printf("Function signature nested inside wrong function "
271*61046927SAndroid Build Coastguard Worker 	     "definition:\n");
272*61046927SAndroid Build Coastguard Worker       printf("%p inside %s %p instead of %s %p\n",
273*61046927SAndroid Build Coastguard Worker 	     (void *) ir,
274*61046927SAndroid Build Coastguard Worker 	     this->current_function->name, (void *) this->current_function,
275*61046927SAndroid Build Coastguard Worker 	     ir->function_name(), (void *) ir->function());
276*61046927SAndroid Build Coastguard Worker       abort();
277*61046927SAndroid Build Coastguard Worker    }
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker    if (ir->return_type == NULL) {
280*61046927SAndroid Build Coastguard Worker       printf("Function signature %p for function %s has NULL return type.\n",
281*61046927SAndroid Build Coastguard Worker 	     (void *) ir, ir->function_name());
282*61046927SAndroid Build Coastguard Worker       abort();
283*61046927SAndroid Build Coastguard Worker    }
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    this->validate_ir(ir, this->data_enter);
286*61046927SAndroid Build Coastguard Worker 
287*61046927SAndroid Build Coastguard Worker    return visit_continue;
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_return * ir)291*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_return *ir)
292*61046927SAndroid Build Coastguard Worker {
293*61046927SAndroid Build Coastguard Worker    if (!this->current_function) {
294*61046927SAndroid Build Coastguard Worker       printf("Return statement outside of a function\n");
295*61046927SAndroid Build Coastguard Worker       abort();
296*61046927SAndroid Build Coastguard Worker    }
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    return visit_continue;
299*61046927SAndroid Build Coastguard Worker }
300*61046927SAndroid Build Coastguard Worker 
301*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_leave(ir_expression * ir)302*61046927SAndroid Build Coastguard Worker ir_validate::visit_leave(ir_expression *ir)
303*61046927SAndroid Build Coastguard Worker {
304*61046927SAndroid Build Coastguard Worker    for (unsigned i = ir->num_operands; i < 4; i++) {
305*61046927SAndroid Build Coastguard Worker       assert(ir->operands[i] == NULL);
306*61046927SAndroid Build Coastguard Worker    }
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ir->num_operands; i++) {
309*61046927SAndroid Build Coastguard Worker       assert(ir->operands[i] != NULL);
310*61046927SAndroid Build Coastguard Worker    }
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker    switch (ir->operation) {
313*61046927SAndroid Build Coastguard Worker    case ir_unop_bit_not:
314*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
315*61046927SAndroid Build Coastguard Worker       break;
316*61046927SAndroid Build Coastguard Worker    case ir_unop_logic_not:
317*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
318*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
319*61046927SAndroid Build Coastguard Worker       break;
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    case ir_unop_neg:
322*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
323*61046927SAndroid Build Coastguard Worker       break;
324*61046927SAndroid Build Coastguard Worker 
325*61046927SAndroid Build Coastguard Worker    case ir_unop_abs:
326*61046927SAndroid Build Coastguard Worker    case ir_unop_sign:
327*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32_64(ir->operands[0]->type) ||
328*61046927SAndroid Build Coastguard Worker              glsl_type_is_float_16_32_64(ir->operands[0]->type));
329*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
330*61046927SAndroid Build Coastguard Worker       break;
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker    case ir_unop_rcp:
333*61046927SAndroid Build Coastguard Worker    case ir_unop_rsq:
334*61046927SAndroid Build Coastguard Worker    case ir_unop_sqrt:
335*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->type));
336*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
337*61046927SAndroid Build Coastguard Worker       break;
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker    case ir_unop_exp:
340*61046927SAndroid Build Coastguard Worker    case ir_unop_log:
341*61046927SAndroid Build Coastguard Worker    case ir_unop_exp2:
342*61046927SAndroid Build Coastguard Worker    case ir_unop_log2:
343*61046927SAndroid Build Coastguard Worker    case ir_unop_saturate:
344*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
345*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
346*61046927SAndroid Build Coastguard Worker       break;
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker    case ir_unop_f2i:
349*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
350*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
351*61046927SAndroid Build Coastguard Worker       break;
352*61046927SAndroid Build Coastguard Worker    case ir_unop_f2u:
353*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
354*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
355*61046927SAndroid Build Coastguard Worker       break;
356*61046927SAndroid Build Coastguard Worker    case ir_unop_i2f:
357*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
358*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->type));
359*61046927SAndroid Build Coastguard Worker       break;
360*61046927SAndroid Build Coastguard Worker    case ir_unop_f2b:
361*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
362*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
363*61046927SAndroid Build Coastguard Worker       break;
364*61046927SAndroid Build Coastguard Worker    case ir_unop_f162b:
365*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type ==
366*61046927SAndroid Build Coastguard Worker              GLSL_TYPE_FLOAT16);
367*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
368*61046927SAndroid Build Coastguard Worker       break;
369*61046927SAndroid Build Coastguard Worker    case ir_unop_b2f:
370*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
371*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->type));
372*61046927SAndroid Build Coastguard Worker       break;
373*61046927SAndroid Build Coastguard Worker    case ir_unop_b2f16:
374*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
375*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
376*61046927SAndroid Build Coastguard Worker       break;
377*61046927SAndroid Build Coastguard Worker    case ir_unop_i2b:
378*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
379*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
380*61046927SAndroid Build Coastguard Worker       break;
381*61046927SAndroid Build Coastguard Worker    case ir_unop_b2i:
382*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
383*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
384*61046927SAndroid Build Coastguard Worker       break;
385*61046927SAndroid Build Coastguard Worker    case ir_unop_u2f:
386*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
387*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->type));
388*61046927SAndroid Build Coastguard Worker       break;
389*61046927SAndroid Build Coastguard Worker    case ir_unop_i2u:
390*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
391*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
392*61046927SAndroid Build Coastguard Worker       break;
393*61046927SAndroid Build Coastguard Worker    case ir_unop_u2i:
394*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
395*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
396*61046927SAndroid Build Coastguard Worker       break;
397*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_i2f:
398*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
399*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT);
400*61046927SAndroid Build Coastguard Worker       break;
401*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_f2i:
402*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
403*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT);
404*61046927SAndroid Build Coastguard Worker       break;
405*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_u2f:
406*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
407*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT);
408*61046927SAndroid Build Coastguard Worker       break;
409*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_f2u:
410*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
411*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT);
412*61046927SAndroid Build Coastguard Worker       break;
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_u642d:
415*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
416*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
417*61046927SAndroid Build Coastguard Worker       break;
418*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_i642d:
419*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
420*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
421*61046927SAndroid Build Coastguard Worker       break;
422*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_d2u64:
423*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
424*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
425*61046927SAndroid Build Coastguard Worker       break;
426*61046927SAndroid Build Coastguard Worker    case ir_unop_bitcast_d2i64:
427*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
428*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
429*61046927SAndroid Build Coastguard Worker       break;
430*61046927SAndroid Build Coastguard Worker    case ir_unop_i642i:
431*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
432*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
433*61046927SAndroid Build Coastguard Worker       break;
434*61046927SAndroid Build Coastguard Worker    case ir_unop_u642i:
435*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
436*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
437*61046927SAndroid Build Coastguard Worker       break;
438*61046927SAndroid Build Coastguard Worker    case ir_unop_i642u:
439*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
440*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
441*61046927SAndroid Build Coastguard Worker       break;
442*61046927SAndroid Build Coastguard Worker    case ir_unop_u642u:
443*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
444*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
445*61046927SAndroid Build Coastguard Worker       break;
446*61046927SAndroid Build Coastguard Worker    case ir_unop_i642b:
447*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
448*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
449*61046927SAndroid Build Coastguard Worker       break;
450*61046927SAndroid Build Coastguard Worker    case ir_unop_i642f:
451*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
452*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->type));
453*61046927SAndroid Build Coastguard Worker       break;
454*61046927SAndroid Build Coastguard Worker    case ir_unop_u642f:
455*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
456*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->type));
457*61046927SAndroid Build Coastguard Worker       break;
458*61046927SAndroid Build Coastguard Worker    case ir_unop_i642d:
459*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
460*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
461*61046927SAndroid Build Coastguard Worker       break;
462*61046927SAndroid Build Coastguard Worker    case ir_unop_u642d:
463*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
464*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
465*61046927SAndroid Build Coastguard Worker       break;
466*61046927SAndroid Build Coastguard Worker    case ir_unop_i2i64:
467*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
468*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
469*61046927SAndroid Build Coastguard Worker       break;
470*61046927SAndroid Build Coastguard Worker    case ir_unop_u2i64:
471*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
472*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
473*61046927SAndroid Build Coastguard Worker       break;
474*61046927SAndroid Build Coastguard Worker    case ir_unop_b2i64:
475*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
476*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
477*61046927SAndroid Build Coastguard Worker       break;
478*61046927SAndroid Build Coastguard Worker    case ir_unop_f2i64:
479*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->operands[0]->type));
480*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
481*61046927SAndroid Build Coastguard Worker       break;
482*61046927SAndroid Build Coastguard Worker    case ir_unop_d2i64:
483*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
484*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
485*61046927SAndroid Build Coastguard Worker       break;
486*61046927SAndroid Build Coastguard Worker    case ir_unop_i2u64:
487*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
488*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
489*61046927SAndroid Build Coastguard Worker       break;
490*61046927SAndroid Build Coastguard Worker    case ir_unop_u2u64:
491*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
492*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
493*61046927SAndroid Build Coastguard Worker       break;
494*61046927SAndroid Build Coastguard Worker    case ir_unop_f2u64:
495*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->operands[0]->type));
496*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
497*61046927SAndroid Build Coastguard Worker       break;
498*61046927SAndroid Build Coastguard Worker    case ir_unop_d2u64:
499*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
500*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
501*61046927SAndroid Build Coastguard Worker       break;
502*61046927SAndroid Build Coastguard Worker    case ir_unop_u642i64:
503*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
504*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
505*61046927SAndroid Build Coastguard Worker       break;
506*61046927SAndroid Build Coastguard Worker    case ir_unop_i642u64:
507*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
508*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
509*61046927SAndroid Build Coastguard Worker       break;
510*61046927SAndroid Build Coastguard Worker    case ir_unop_trunc:
511*61046927SAndroid Build Coastguard Worker    case ir_unop_round_even:
512*61046927SAndroid Build Coastguard Worker    case ir_unop_ceil:
513*61046927SAndroid Build Coastguard Worker    case ir_unop_floor:
514*61046927SAndroid Build Coastguard Worker    case ir_unop_fract:
515*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
516*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
517*61046927SAndroid Build Coastguard Worker       break;
518*61046927SAndroid Build Coastguard Worker    case ir_unop_sin:
519*61046927SAndroid Build Coastguard Worker    case ir_unop_cos:
520*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdx:
521*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdx_coarse:
522*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdx_fine:
523*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdy:
524*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdy_coarse:
525*61046927SAndroid Build Coastguard Worker    case ir_unop_dFdy_fine:
526*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
527*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
528*61046927SAndroid Build Coastguard Worker       break;
529*61046927SAndroid Build Coastguard Worker 
530*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_snorm_2x16:
531*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_unorm_2x16:
532*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_half_2x16:
533*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uint);
534*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_vec2);
535*61046927SAndroid Build Coastguard Worker       break;
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_snorm_4x8:
538*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_unorm_4x8:
539*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uint);
540*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_vec4);
541*61046927SAndroid Build Coastguard Worker       break;
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_double_2x32:
544*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_double);
545*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uvec2);
546*61046927SAndroid Build Coastguard Worker       break;
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_int_2x32:
549*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_int64_t);
550*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_ivec2);
551*61046927SAndroid Build Coastguard Worker       break;
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_uint_2x32:
554*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uint64_t);
555*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uvec2);
556*61046927SAndroid Build Coastguard Worker       break;
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_sampler_2x32:
559*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_sampler(ir->type));
560*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uvec2);
561*61046927SAndroid Build Coastguard Worker       break;
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker    case ir_unop_pack_image_2x32:
564*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_image(ir->type));
565*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uvec2);
566*61046927SAndroid Build Coastguard Worker       break;
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_snorm_2x16:
569*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_unorm_2x16:
570*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_half_2x16:
571*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_vec2);
572*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uint);
573*61046927SAndroid Build Coastguard Worker       break;
574*61046927SAndroid Build Coastguard Worker 
575*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_snorm_4x8:
576*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_unorm_4x8:
577*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_vec4);
578*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uint);
579*61046927SAndroid Build Coastguard Worker       break;
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_double_2x32:
582*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uvec2);
583*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_double);
584*61046927SAndroid Build Coastguard Worker       break;
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_int_2x32:
587*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_ivec2);
588*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_int64_t);
589*61046927SAndroid Build Coastguard Worker       break;
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_uint_2x32:
592*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uvec2);
593*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uint64_t);
594*61046927SAndroid Build Coastguard Worker       break;
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_sampler_2x32:
597*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uvec2);
598*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_sampler(ir->operands[0]->type));
599*61046927SAndroid Build Coastguard Worker       break;
600*61046927SAndroid Build Coastguard Worker 
601*61046927SAndroid Build Coastguard Worker    case ir_unop_unpack_image_2x32:
602*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_uvec2);
603*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_image(ir->operands[0]->type));
604*61046927SAndroid Build Coastguard Worker       break;
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker    case ir_unop_bitfield_reverse:
607*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
608*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_32(ir->type));
609*61046927SAndroid Build Coastguard Worker       break;
610*61046927SAndroid Build Coastguard Worker 
611*61046927SAndroid Build Coastguard Worker    case ir_unop_bit_count:
612*61046927SAndroid Build Coastguard Worker    case ir_unop_find_msb:
613*61046927SAndroid Build Coastguard Worker    case ir_unop_find_lsb:
614*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->vector_elements == ir->type->vector_elements);
615*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32(ir->operands[0]->type));
616*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
617*61046927SAndroid Build Coastguard Worker       break;
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker    case ir_unop_clz:
620*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
621*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
622*61046927SAndroid Build Coastguard Worker       break;
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker    case ir_unop_interpolate_at_centroid:
625*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
626*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
627*61046927SAndroid Build Coastguard Worker       break;
628*61046927SAndroid Build Coastguard Worker 
629*61046927SAndroid Build Coastguard Worker    case ir_unop_get_buffer_size:
630*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_int);
631*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == &glsl_type_builtin_uint);
632*61046927SAndroid Build Coastguard Worker       break;
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker    case ir_unop_ssbo_unsized_array_length:
635*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_int);
636*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_array(ir->operands[0]->type));
637*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_unsized_array(ir->operands[0]->type));
638*61046927SAndroid Build Coastguard Worker       break;
639*61046927SAndroid Build Coastguard Worker 
640*61046927SAndroid Build Coastguard Worker    case ir_unop_implicitly_sized_array_length:
641*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_int);
642*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_array(ir->operands[0]->type));
643*61046927SAndroid Build Coastguard Worker       break;
644*61046927SAndroid Build Coastguard Worker 
645*61046927SAndroid Build Coastguard Worker    case ir_unop_d2f:
646*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
647*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->type));
648*61046927SAndroid Build Coastguard Worker       break;
649*61046927SAndroid Build Coastguard Worker    case ir_unop_f2d:
650*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->operands[0]->type));
651*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
652*61046927SAndroid Build Coastguard Worker       break;
653*61046927SAndroid Build Coastguard Worker    case ir_unop_f162f:
654*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
655*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->type));
656*61046927SAndroid Build Coastguard Worker       break;
657*61046927SAndroid Build Coastguard Worker    case ir_unop_f2f16:
658*61046927SAndroid Build Coastguard Worker    case ir_unop_f2fmp:
659*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float(ir->operands[0]->type));
660*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
661*61046927SAndroid Build Coastguard Worker       break;
662*61046927SAndroid Build Coastguard Worker    case ir_unop_i2i:
663*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
664*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
665*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type != ir->operands[0]->type->base_type);
666*61046927SAndroid Build Coastguard Worker       break;
667*61046927SAndroid Build Coastguard Worker    case ir_unop_u2u:
668*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
669*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
670*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type != ir->operands[0]->type->base_type);
671*61046927SAndroid Build Coastguard Worker       break;
672*61046927SAndroid Build Coastguard Worker    case ir_unop_i2imp:
673*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
674*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT16);
675*61046927SAndroid Build Coastguard Worker       break;
676*61046927SAndroid Build Coastguard Worker    case ir_unop_u2ump:
677*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
678*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT16);
679*61046927SAndroid Build Coastguard Worker       break;
680*61046927SAndroid Build Coastguard Worker    case ir_unop_d2i:
681*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
682*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
683*61046927SAndroid Build Coastguard Worker       break;
684*61046927SAndroid Build Coastguard Worker    case ir_unop_i2d:
685*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
686*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
687*61046927SAndroid Build Coastguard Worker       break;
688*61046927SAndroid Build Coastguard Worker    case ir_unop_d2u:
689*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
690*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
691*61046927SAndroid Build Coastguard Worker       break;
692*61046927SAndroid Build Coastguard Worker    case ir_unop_u2d:
693*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
694*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
695*61046927SAndroid Build Coastguard Worker       break;
696*61046927SAndroid Build Coastguard Worker    case ir_unop_d2b:
697*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
698*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
699*61046927SAndroid Build Coastguard Worker       break;
700*61046927SAndroid Build Coastguard Worker    case ir_unop_u2f16:
701*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
702*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->operands[0]->type));
703*61046927SAndroid Build Coastguard Worker       break;
704*61046927SAndroid Build Coastguard Worker    case ir_unop_f162u:
705*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32(ir->type));
706*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
707*61046927SAndroid Build Coastguard Worker       break;
708*61046927SAndroid Build Coastguard Worker    case ir_unop_i2f16:
709*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
710*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->operands[0]->type));
711*61046927SAndroid Build Coastguard Worker       break;
712*61046927SAndroid Build Coastguard Worker    case ir_unop_f162i:
713*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_int_16_32(ir->type));
714*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
715*61046927SAndroid Build Coastguard Worker       break;
716*61046927SAndroid Build Coastguard Worker    case ir_unop_d2f16:
717*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
718*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->operands[0]->type));
719*61046927SAndroid Build Coastguard Worker       break;
720*61046927SAndroid Build Coastguard Worker    case ir_unop_f162d:
721*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_double(ir->type));
722*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
723*61046927SAndroid Build Coastguard Worker       break;
724*61046927SAndroid Build Coastguard Worker    case ir_unop_u642f16:
725*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
726*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
727*61046927SAndroid Build Coastguard Worker       break;
728*61046927SAndroid Build Coastguard Worker    case ir_unop_f162u64:
729*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT64);
730*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
731*61046927SAndroid Build Coastguard Worker       break;
732*61046927SAndroid Build Coastguard Worker    case ir_unop_i642f16:
733*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
734*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
735*61046927SAndroid Build Coastguard Worker       break;
736*61046927SAndroid Build Coastguard Worker    case ir_unop_f162i64:
737*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT64);
738*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT16);
739*61046927SAndroid Build Coastguard Worker       break;
740*61046927SAndroid Build Coastguard Worker 
741*61046927SAndroid Build Coastguard Worker    case ir_unop_frexp_sig:
742*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
743*61046927SAndroid Build Coastguard Worker       break;
744*61046927SAndroid Build Coastguard Worker    case ir_unop_frexp_exp:
745*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
746*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT);
747*61046927SAndroid Build Coastguard Worker       break;
748*61046927SAndroid Build Coastguard Worker    case ir_unop_subroutine_to_int:
749*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
750*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_INT);
751*61046927SAndroid Build Coastguard Worker       break;
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker    case ir_unop_atan:
754*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
755*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
756*61046927SAndroid Build Coastguard Worker       break;
757*61046927SAndroid Build Coastguard Worker 
758*61046927SAndroid Build Coastguard Worker    case ir_binop_add:
759*61046927SAndroid Build Coastguard Worker    case ir_binop_sub:
760*61046927SAndroid Build Coastguard Worker    case ir_binop_mul:
761*61046927SAndroid Build Coastguard Worker    case ir_binop_div:
762*61046927SAndroid Build Coastguard Worker    case ir_binop_mod:
763*61046927SAndroid Build Coastguard Worker    case ir_binop_min:
764*61046927SAndroid Build Coastguard Worker    case ir_binop_max:
765*61046927SAndroid Build Coastguard Worker    case ir_binop_pow:
766*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type ==
767*61046927SAndroid Build Coastguard Worker              ir->operands[1]->type->base_type);
768*61046927SAndroid Build Coastguard Worker 
769*61046927SAndroid Build Coastguard Worker       if (ir->operation == ir_binop_mul &&
770*61046927SAndroid Build Coastguard Worker           (ir->type->base_type == GLSL_TYPE_UINT64 ||
771*61046927SAndroid Build Coastguard Worker            ir->type->base_type == GLSL_TYPE_INT64) &&
772*61046927SAndroid Build Coastguard Worker           (glsl_type_is_int_16_32(ir->operands[0]->type)||
773*61046927SAndroid Build Coastguard Worker            glsl_type_is_int_16_32(ir->operands[1]->type)||
774*61046927SAndroid Build Coastguard Worker            glsl_type_is_uint_16_32(ir->operands[0]->type) ||
775*61046927SAndroid Build Coastguard Worker            glsl_type_is_uint_16_32(ir->operands[1]->type))) {
776*61046927SAndroid Build Coastguard Worker          assert(ir->operands[0]->type == ir->operands[1]->type);
777*61046927SAndroid Build Coastguard Worker          break;
778*61046927SAndroid Build Coastguard Worker       }
779*61046927SAndroid Build Coastguard Worker 
780*61046927SAndroid Build Coastguard Worker       if (glsl_type_is_scalar(ir->operands[0]->type))
781*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[1]->type == ir->type);
782*61046927SAndroid Build Coastguard Worker       else if (glsl_type_is_scalar(ir->operands[1]->type))
783*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type == ir->type);
784*61046927SAndroid Build Coastguard Worker       else if (glsl_type_is_vector(ir->operands[0]->type) &&
785*61046927SAndroid Build Coastguard Worker 	       glsl_type_is_vector(ir->operands[1]->type)) {
786*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type == ir->operands[1]->type);
787*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type == ir->type);
788*61046927SAndroid Build Coastguard Worker       }
789*61046927SAndroid Build Coastguard Worker       break;
790*61046927SAndroid Build Coastguard Worker 
791*61046927SAndroid Build Coastguard Worker    case ir_binop_abs_sub:
792*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->operands[1]->type);
793*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32_64(ir->operands[0]->type));
794*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->vector_elements ==
795*61046927SAndroid Build Coastguard Worker              ir->type->vector_elements);
796*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_uint_16_32_64(ir->type));
797*61046927SAndroid Build Coastguard Worker       break;
798*61046927SAndroid Build Coastguard Worker 
799*61046927SAndroid Build Coastguard Worker    case ir_binop_add_sat:
800*61046927SAndroid Build Coastguard Worker    case ir_binop_sub_sat:
801*61046927SAndroid Build Coastguard Worker    case ir_binop_avg:
802*61046927SAndroid Build Coastguard Worker    case ir_binop_avg_round:
803*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
804*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[1]->type);
805*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32_64(ir->type));
806*61046927SAndroid Build Coastguard Worker       break;
807*61046927SAndroid Build Coastguard Worker 
808*61046927SAndroid Build Coastguard Worker    case ir_binop_mul_32x16:
809*61046927SAndroid Build Coastguard Worker    case ir_binop_imul_high:
810*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
811*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[1]->type);
812*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_32(ir->type));
813*61046927SAndroid Build Coastguard Worker       break;
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker    case ir_binop_carry:
816*61046927SAndroid Build Coastguard Worker    case ir_binop_borrow:
817*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
818*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[1]->type);
819*61046927SAndroid Build Coastguard Worker       assert(ir->type->base_type == GLSL_TYPE_UINT);
820*61046927SAndroid Build Coastguard Worker       break;
821*61046927SAndroid Build Coastguard Worker 
822*61046927SAndroid Build Coastguard Worker    case ir_binop_less:
823*61046927SAndroid Build Coastguard Worker    case ir_binop_gequal:
824*61046927SAndroid Build Coastguard Worker    case ir_binop_equal:
825*61046927SAndroid Build Coastguard Worker    case ir_binop_nequal:
826*61046927SAndroid Build Coastguard Worker       /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
827*61046927SAndroid Build Coastguard Worker        * ==, and != operators.  The IR operators perform a component-wise
828*61046927SAndroid Build Coastguard Worker        * comparison on scalar or vector types and return a boolean scalar or
829*61046927SAndroid Build Coastguard Worker        * vector type of the same size.
830*61046927SAndroid Build Coastguard Worker        */
831*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
832*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->operands[1]->type);
833*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_vector(ir->operands[0]->type)
834*61046927SAndroid Build Coastguard Worker 	     || glsl_type_is_scalar(ir->operands[0]->type));
835*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->vector_elements
836*61046927SAndroid Build Coastguard Worker 	     == ir->type->vector_elements);
837*61046927SAndroid Build Coastguard Worker       break;
838*61046927SAndroid Build Coastguard Worker 
839*61046927SAndroid Build Coastguard Worker    case ir_binop_all_equal:
840*61046927SAndroid Build Coastguard Worker    case ir_binop_any_nequal:
841*61046927SAndroid Build Coastguard Worker       /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
842*61046927SAndroid Build Coastguard Worker        * return a scalar boolean.  The IR matches that.
843*61046927SAndroid Build Coastguard Worker        */
844*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_bool);
845*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->operands[1]->type);
846*61046927SAndroid Build Coastguard Worker       break;
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker    case ir_binop_lshift:
849*61046927SAndroid Build Coastguard Worker    case ir_binop_rshift:
850*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32_64(ir->operands[0]->type) &&
851*61046927SAndroid Build Coastguard Worker              glsl_type_is_integer_16_32_64(ir->operands[1]->type));
852*61046927SAndroid Build Coastguard Worker       if (glsl_type_is_scalar(ir->operands[0]->type)) {
853*61046927SAndroid Build Coastguard Worker           assert(glsl_type_is_scalar(ir->operands[1]->type));
854*61046927SAndroid Build Coastguard Worker       }
855*61046927SAndroid Build Coastguard Worker       if (glsl_type_is_vector(ir->operands[0]->type) &&
856*61046927SAndroid Build Coastguard Worker           glsl_type_is_vector(ir->operands[1]->type)) {
857*61046927SAndroid Build Coastguard Worker           assert(glsl_get_components(ir->operands[0]->type) ==
858*61046927SAndroid Build Coastguard Worker                  glsl_get_components(ir->operands[1]->type));
859*61046927SAndroid Build Coastguard Worker       }
860*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
861*61046927SAndroid Build Coastguard Worker       break;
862*61046927SAndroid Build Coastguard Worker 
863*61046927SAndroid Build Coastguard Worker    case ir_binop_bit_and:
864*61046927SAndroid Build Coastguard Worker    case ir_binop_bit_xor:
865*61046927SAndroid Build Coastguard Worker    case ir_binop_bit_or:
866*61046927SAndroid Build Coastguard Worker        assert(ir->operands[0]->type->base_type ==
867*61046927SAndroid Build Coastguard Worker               ir->operands[1]->type->base_type);
868*61046927SAndroid Build Coastguard Worker        assert(glsl_type_is_integer_16_32_64(ir->type));
869*61046927SAndroid Build Coastguard Worker        if (glsl_type_is_vector(ir->operands[0]->type) &&
870*61046927SAndroid Build Coastguard Worker            glsl_type_is_vector(ir->operands[1]->type)) {
871*61046927SAndroid Build Coastguard Worker            assert(ir->operands[0]->type->vector_elements ==
872*61046927SAndroid Build Coastguard Worker                   ir->operands[1]->type->vector_elements);
873*61046927SAndroid Build Coastguard Worker        }
874*61046927SAndroid Build Coastguard Worker        break;
875*61046927SAndroid Build Coastguard Worker 
876*61046927SAndroid Build Coastguard Worker    case ir_binop_logic_and:
877*61046927SAndroid Build Coastguard Worker    case ir_binop_logic_xor:
878*61046927SAndroid Build Coastguard Worker    case ir_binop_logic_or:
879*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->type));
880*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
881*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[1]->type));
882*61046927SAndroid Build Coastguard Worker       break;
883*61046927SAndroid Build Coastguard Worker 
884*61046927SAndroid Build Coastguard Worker    case ir_binop_dot:
885*61046927SAndroid Build Coastguard Worker       assert(ir->type == &glsl_type_builtin_float ||
886*61046927SAndroid Build Coastguard Worker              ir->type == &glsl_type_builtin_double ||
887*61046927SAndroid Build Coastguard Worker              ir->type == &glsl_type_builtin_float16_t);
888*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
889*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_vector(ir->operands[0]->type));
890*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->operands[1]->type);
891*61046927SAndroid Build Coastguard Worker       break;
892*61046927SAndroid Build Coastguard Worker 
893*61046927SAndroid Build Coastguard Worker    case ir_binop_ldexp:
894*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
895*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
896*61046927SAndroid Build Coastguard Worker       assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT);
897*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(ir->operands[0]->type) ==
898*61046927SAndroid Build Coastguard Worker              glsl_get_components(ir->operands[1]->type));
899*61046927SAndroid Build Coastguard Worker       break;
900*61046927SAndroid Build Coastguard Worker 
901*61046927SAndroid Build Coastguard Worker    case ir_binop_vector_extract:
902*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_vector(ir->operands[0]->type));
903*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_scalar(ir->operands[1]->type)
904*61046927SAndroid Build Coastguard Worker              && glsl_type_is_integer_16_32(ir->operands[1]->type));
905*61046927SAndroid Build Coastguard Worker       break;
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker    case ir_binop_interpolate_at_offset:
908*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
909*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
910*61046927SAndroid Build Coastguard Worker       assert(glsl_get_components(ir->operands[1]->type) == 2);
911*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[1]->type));
912*61046927SAndroid Build Coastguard Worker       break;
913*61046927SAndroid Build Coastguard Worker 
914*61046927SAndroid Build Coastguard Worker    case ir_binop_interpolate_at_sample:
915*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
916*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32(ir->operands[0]->type));
917*61046927SAndroid Build Coastguard Worker       assert(ir->operands[1]->type == &glsl_type_builtin_int ||
918*61046927SAndroid Build Coastguard Worker              ir->operands[1]->type == &glsl_type_builtin_int16_t);
919*61046927SAndroid Build Coastguard Worker       break;
920*61046927SAndroid Build Coastguard Worker 
921*61046927SAndroid Build Coastguard Worker    case ir_binop_atan2:
922*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
923*61046927SAndroid Build Coastguard Worker       assert(ir->operands[1]->type == ir->operands[0]->type);
924*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
925*61046927SAndroid Build Coastguard Worker       break;
926*61046927SAndroid Build Coastguard Worker 
927*61046927SAndroid Build Coastguard Worker    case ir_triop_fma:
928*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->type));
929*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
930*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[1]->type);
931*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[2]->type);
932*61046927SAndroid Build Coastguard Worker       break;
933*61046927SAndroid Build Coastguard Worker 
934*61046927SAndroid Build Coastguard Worker    case ir_triop_lrp:
935*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_float_16_32_64(ir->operands[0]->type));
936*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->operands[1]->type);
937*61046927SAndroid Build Coastguard Worker       assert(ir->operands[2]->type == ir->operands[0]->type ||
938*61046927SAndroid Build Coastguard Worker              ir->operands[2]->type == &glsl_type_builtin_float ||
939*61046927SAndroid Build Coastguard Worker              ir->operands[2]->type == &glsl_type_builtin_double ||
940*61046927SAndroid Build Coastguard Worker              ir->operands[2]->type == &glsl_type_builtin_float16_t);
941*61046927SAndroid Build Coastguard Worker       break;
942*61046927SAndroid Build Coastguard Worker 
943*61046927SAndroid Build Coastguard Worker    case ir_triop_csel:
944*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_boolean(ir->operands[0]->type));
945*61046927SAndroid Build Coastguard Worker       assert(ir->type->vector_elements == ir->operands[0]->type->vector_elements);
946*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[1]->type);
947*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[2]->type);
948*61046927SAndroid Build Coastguard Worker       break;
949*61046927SAndroid Build Coastguard Worker 
950*61046927SAndroid Build Coastguard Worker    case ir_triop_bitfield_extract:
951*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32(ir->type));
952*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
953*61046927SAndroid Build Coastguard Worker       assert(ir->operands[1]->type == ir->type);
954*61046927SAndroid Build Coastguard Worker       assert(ir->operands[2]->type == ir->type);
955*61046927SAndroid Build Coastguard Worker       break;
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker    case ir_triop_vector_insert:
958*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_vector(ir->operands[0]->type));
959*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_scalar(ir->operands[1]->type));
960*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type->base_type == ir->operands[1]->type->base_type);
961*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_scalar(ir->operands[2]->type)
962*61046927SAndroid Build Coastguard Worker              && glsl_type_is_integer_16_32(ir->operands[2]->type));
963*61046927SAndroid Build Coastguard Worker       assert(ir->type == ir->operands[0]->type);
964*61046927SAndroid Build Coastguard Worker       break;
965*61046927SAndroid Build Coastguard Worker 
966*61046927SAndroid Build Coastguard Worker    case ir_quadop_bitfield_insert:
967*61046927SAndroid Build Coastguard Worker       assert(glsl_type_is_integer_16_32(ir->type));
968*61046927SAndroid Build Coastguard Worker       assert(ir->operands[0]->type == ir->type);
969*61046927SAndroid Build Coastguard Worker       assert(ir->operands[1]->type == ir->type);
970*61046927SAndroid Build Coastguard Worker       assert(ir->operands[2]->type == ir->type);
971*61046927SAndroid Build Coastguard Worker       assert(ir->operands[3]->type == ir->type);
972*61046927SAndroid Build Coastguard Worker       break;
973*61046927SAndroid Build Coastguard Worker 
974*61046927SAndroid Build Coastguard Worker    case ir_quadop_vector:
975*61046927SAndroid Build Coastguard Worker       /* The vector operator collects some number of scalars and generates a
976*61046927SAndroid Build Coastguard Worker        * vector from them.
977*61046927SAndroid Build Coastguard Worker        *
978*61046927SAndroid Build Coastguard Worker        *  - All of the operands must be scalar.
979*61046927SAndroid Build Coastguard Worker        *  - Number of operands must matche the size of the resulting vector.
980*61046927SAndroid Build Coastguard Worker        *  - Base type of the operands must match the base type of the result.
981*61046927SAndroid Build Coastguard Worker        */
982*61046927SAndroid Build Coastguard Worker       switch (ir->type->vector_elements) {
983*61046927SAndroid Build Coastguard Worker       case 1:
984*61046927SAndroid Build Coastguard Worker          assert(glsl_type_is_scalar(ir->operands[0]->type));
985*61046927SAndroid Build Coastguard Worker          assert(ir->operands[0]->type->base_type == ir->type->base_type);
986*61046927SAndroid Build Coastguard Worker          assert(ir->operands[1] == NULL);
987*61046927SAndroid Build Coastguard Worker          assert(ir->operands[2] == NULL);
988*61046927SAndroid Build Coastguard Worker          assert(ir->operands[3] == NULL);
989*61046927SAndroid Build Coastguard Worker          break;
990*61046927SAndroid Build Coastguard Worker       case 2:
991*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[0]->type));
992*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
993*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[1]->type));
994*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
995*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[2] == NULL);
996*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[3] == NULL);
997*61046927SAndroid Build Coastguard Worker 	 break;
998*61046927SAndroid Build Coastguard Worker       case 3:
999*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[0]->type));
1000*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
1001*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[1]->type));
1002*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
1003*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[2]->type));
1004*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
1005*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[3] == NULL);
1006*61046927SAndroid Build Coastguard Worker 	 break;
1007*61046927SAndroid Build Coastguard Worker       case 4:
1008*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[0]->type));
1009*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
1010*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[1]->type));
1011*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
1012*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[2]->type));
1013*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
1014*61046927SAndroid Build Coastguard Worker 	 assert(glsl_type_is_scalar(ir->operands[3]->type));
1015*61046927SAndroid Build Coastguard Worker 	 assert(ir->operands[3]->type->base_type == ir->type->base_type);
1016*61046927SAndroid Build Coastguard Worker 	 break;
1017*61046927SAndroid Build Coastguard Worker       default:
1018*61046927SAndroid Build Coastguard Worker 	 /* The is_vector assertion above should prevent execution from ever
1019*61046927SAndroid Build Coastguard Worker 	  * getting here.
1020*61046927SAndroid Build Coastguard Worker 	  */
1021*61046927SAndroid Build Coastguard Worker 	 assert(!"Should not get here.");
1022*61046927SAndroid Build Coastguard Worker 	 break;
1023*61046927SAndroid Build Coastguard Worker       }
1024*61046927SAndroid Build Coastguard Worker    }
1025*61046927SAndroid Build Coastguard Worker 
1026*61046927SAndroid Build Coastguard Worker    return visit_continue;
1027*61046927SAndroid Build Coastguard Worker }
1028*61046927SAndroid Build Coastguard Worker 
1029*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_leave(ir_swizzle * ir)1030*61046927SAndroid Build Coastguard Worker ir_validate::visit_leave(ir_swizzle *ir)
1031*61046927SAndroid Build Coastguard Worker {
1032*61046927SAndroid Build Coastguard Worker    unsigned int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
1033*61046927SAndroid Build Coastguard Worker 
1034*61046927SAndroid Build Coastguard Worker    for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
1035*61046927SAndroid Build Coastguard Worker       if (chans[i] >= ir->val->type->vector_elements) {
1036*61046927SAndroid Build Coastguard Worker 	 printf("ir_swizzle @ %p specifies a channel not present "
1037*61046927SAndroid Build Coastguard Worker 		"in the value.\n", (void *) ir);
1038*61046927SAndroid Build Coastguard Worker 	 ir->print();
1039*61046927SAndroid Build Coastguard Worker 	 abort();
1040*61046927SAndroid Build Coastguard Worker       }
1041*61046927SAndroid Build Coastguard Worker    }
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    return visit_continue;
1044*61046927SAndroid Build Coastguard Worker }
1045*61046927SAndroid Build Coastguard Worker 
1046*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit(ir_variable * ir)1047*61046927SAndroid Build Coastguard Worker ir_validate::visit(ir_variable *ir)
1048*61046927SAndroid Build Coastguard Worker {
1049*61046927SAndroid Build Coastguard Worker    /* An ir_variable is the one thing that can (and will) appear multiple times
1050*61046927SAndroid Build Coastguard Worker     * in an IR tree.  It is added to the hashtable so that it can be used
1051*61046927SAndroid Build Coastguard Worker     * in the ir_dereference_variable handler to ensure that a variable is
1052*61046927SAndroid Build Coastguard Worker     * declared before it is dereferenced.
1053*61046927SAndroid Build Coastguard Worker     */
1054*61046927SAndroid Build Coastguard Worker    if (ir->name && ir->is_name_ralloced())
1055*61046927SAndroid Build Coastguard Worker       assert(ralloc_parent(ir->name) == ir);
1056*61046927SAndroid Build Coastguard Worker 
1057*61046927SAndroid Build Coastguard Worker    _mesa_set_add(ir_set, ir);
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker    /* If a variable is an array, verify that the maximum array index is in
1060*61046927SAndroid Build Coastguard Worker     * bounds.  There was once an error in AST-to-HIR conversion that set this
1061*61046927SAndroid Build Coastguard Worker     * to be out of bounds.
1062*61046927SAndroid Build Coastguard Worker     */
1063*61046927SAndroid Build Coastguard Worker    if (glsl_array_size(ir->type) > 0) {
1064*61046927SAndroid Build Coastguard Worker       if (ir->data.max_array_access >= (int)ir->type->length) {
1065*61046927SAndroid Build Coastguard Worker 	 printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
1066*61046927SAndroid Build Coastguard Worker 		ir->data.max_array_access, ir->type->length - 1);
1067*61046927SAndroid Build Coastguard Worker 	 ir->print();
1068*61046927SAndroid Build Coastguard Worker 	 abort();
1069*61046927SAndroid Build Coastguard Worker       }
1070*61046927SAndroid Build Coastguard Worker    }
1071*61046927SAndroid Build Coastguard Worker 
1072*61046927SAndroid Build Coastguard Worker    /* If a variable is an interface block (or an array of interface blocks),
1073*61046927SAndroid Build Coastguard Worker     * verify that the maximum array index for each interface member is in
1074*61046927SAndroid Build Coastguard Worker     * bounds.
1075*61046927SAndroid Build Coastguard Worker     */
1076*61046927SAndroid Build Coastguard Worker    if (ir->is_interface_instance()) {
1077*61046927SAndroid Build Coastguard Worker       const glsl_struct_field *fields =
1078*61046927SAndroid Build Coastguard Worker          ir->get_interface_type()->fields.structure;
1079*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < ir->get_interface_type()->length; i++) {
1080*61046927SAndroid Build Coastguard Worker          if (glsl_array_size(fields[i].type) > 0 &&
1081*61046927SAndroid Build Coastguard Worker              !fields[i].implicit_sized_array) {
1082*61046927SAndroid Build Coastguard Worker             const int *const max_ifc_array_access =
1083*61046927SAndroid Build Coastguard Worker                ir->get_max_ifc_array_access();
1084*61046927SAndroid Build Coastguard Worker 
1085*61046927SAndroid Build Coastguard Worker             assert(max_ifc_array_access != NULL);
1086*61046927SAndroid Build Coastguard Worker 
1087*61046927SAndroid Build Coastguard Worker             if (max_ifc_array_access[i] >= (int)fields[i].type->length) {
1088*61046927SAndroid Build Coastguard Worker                printf("ir_variable has maximum access out of bounds for "
1089*61046927SAndroid Build Coastguard Worker                       "field %s (%d vs %d)\n", fields[i].name,
1090*61046927SAndroid Build Coastguard Worker                       max_ifc_array_access[i], fields[i].type->length);
1091*61046927SAndroid Build Coastguard Worker                ir->print();
1092*61046927SAndroid Build Coastguard Worker                abort();
1093*61046927SAndroid Build Coastguard Worker             }
1094*61046927SAndroid Build Coastguard Worker          }
1095*61046927SAndroid Build Coastguard Worker       }
1096*61046927SAndroid Build Coastguard Worker    }
1097*61046927SAndroid Build Coastguard Worker 
1098*61046927SAndroid Build Coastguard Worker    if (ir->constant_initializer != NULL && !ir->data.has_initializer) {
1099*61046927SAndroid Build Coastguard Worker       printf("ir_variable didn't have an initializer, but has a constant "
1100*61046927SAndroid Build Coastguard Worker 	     "initializer value.\n");
1101*61046927SAndroid Build Coastguard Worker       ir->print();
1102*61046927SAndroid Build Coastguard Worker       abort();
1103*61046927SAndroid Build Coastguard Worker    }
1104*61046927SAndroid Build Coastguard Worker 
1105*61046927SAndroid Build Coastguard Worker    if (ir->data.mode == ir_var_uniform
1106*61046927SAndroid Build Coastguard Worker        && is_gl_identifier(ir->name)
1107*61046927SAndroid Build Coastguard Worker        && ir->get_state_slots() == NULL) {
1108*61046927SAndroid Build Coastguard Worker       printf("built-in uniform has no state\n");
1109*61046927SAndroid Build Coastguard Worker       ir->print();
1110*61046927SAndroid Build Coastguard Worker       abort();
1111*61046927SAndroid Build Coastguard Worker    }
1112*61046927SAndroid Build Coastguard Worker 
1113*61046927SAndroid Build Coastguard Worker    return visit_continue;
1114*61046927SAndroid Build Coastguard Worker }
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_assignment * ir)1117*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_assignment *ir)
1118*61046927SAndroid Build Coastguard Worker {
1119*61046927SAndroid Build Coastguard Worker    const ir_dereference *const lhs = ir->lhs;
1120*61046927SAndroid Build Coastguard Worker    if (glsl_type_is_scalar(lhs->type) || glsl_type_is_vector(lhs->type)) {
1121*61046927SAndroid Build Coastguard Worker       if (ir->write_mask == 0) {
1122*61046927SAndroid Build Coastguard Worker 	 printf("Assignment LHS is %s, but write mask is 0:\n",
1123*61046927SAndroid Build Coastguard Worker 		glsl_type_is_scalar(lhs->type) ? "scalar" : "vector");
1124*61046927SAndroid Build Coastguard Worker 	 ir->print();
1125*61046927SAndroid Build Coastguard Worker 	 abort();
1126*61046927SAndroid Build Coastguard Worker       }
1127*61046927SAndroid Build Coastguard Worker 
1128*61046927SAndroid Build Coastguard Worker       int lhs_components = 0;
1129*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < 4; i++) {
1130*61046927SAndroid Build Coastguard Worker 	 if (ir->write_mask & (1 << i))
1131*61046927SAndroid Build Coastguard Worker 	    lhs_components++;
1132*61046927SAndroid Build Coastguard Worker       }
1133*61046927SAndroid Build Coastguard Worker 
1134*61046927SAndroid Build Coastguard Worker       if (lhs_components != ir->rhs->type->vector_elements) {
1135*61046927SAndroid Build Coastguard Worker 	 printf("Assignment count of LHS write mask channels enabled not\n"
1136*61046927SAndroid Build Coastguard Worker 		"matching RHS vector size (%d LHS, %d RHS).\n",
1137*61046927SAndroid Build Coastguard Worker 		lhs_components, ir->rhs->type->vector_elements);
1138*61046927SAndroid Build Coastguard Worker 	 ir->print();
1139*61046927SAndroid Build Coastguard Worker 	 abort();
1140*61046927SAndroid Build Coastguard Worker       }
1141*61046927SAndroid Build Coastguard Worker    }
1142*61046927SAndroid Build Coastguard Worker 
1143*61046927SAndroid Build Coastguard Worker    if (lhs->type->base_type != ir->rhs->type->base_type) {
1144*61046927SAndroid Build Coastguard Worker       printf("Assignment LHS and RHS base types are different:\n");
1145*61046927SAndroid Build Coastguard Worker       lhs->print();
1146*61046927SAndroid Build Coastguard Worker       printf("\n");
1147*61046927SAndroid Build Coastguard Worker       ir->rhs->print();
1148*61046927SAndroid Build Coastguard Worker       printf("\n");
1149*61046927SAndroid Build Coastguard Worker       abort();
1150*61046927SAndroid Build Coastguard Worker    }
1151*61046927SAndroid Build Coastguard Worker 
1152*61046927SAndroid Build Coastguard Worker    this->validate_ir(ir, this->data_enter);
1153*61046927SAndroid Build Coastguard Worker 
1154*61046927SAndroid Build Coastguard Worker    return visit_continue;
1155*61046927SAndroid Build Coastguard Worker }
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker ir_visitor_status
visit_enter(ir_call * ir)1158*61046927SAndroid Build Coastguard Worker ir_validate::visit_enter(ir_call *ir)
1159*61046927SAndroid Build Coastguard Worker {
1160*61046927SAndroid Build Coastguard Worker    ir_function_signature *const callee = ir->callee;
1161*61046927SAndroid Build Coastguard Worker 
1162*61046927SAndroid Build Coastguard Worker    if (callee->ir_type != ir_type_function_signature) {
1163*61046927SAndroid Build Coastguard Worker       printf("IR called by ir_call is not ir_function_signature!\n");
1164*61046927SAndroid Build Coastguard Worker       abort();
1165*61046927SAndroid Build Coastguard Worker    }
1166*61046927SAndroid Build Coastguard Worker 
1167*61046927SAndroid Build Coastguard Worker    if (ir->return_deref) {
1168*61046927SAndroid Build Coastguard Worker       if (ir->return_deref->type != callee->return_type) {
1169*61046927SAndroid Build Coastguard Worker 	 printf("callee type %s does not match return storage type %s\n",
1170*61046927SAndroid Build Coastguard Worker 	        glsl_get_type_name(callee->return_type), glsl_get_type_name(ir->return_deref->type));
1171*61046927SAndroid Build Coastguard Worker 	 abort();
1172*61046927SAndroid Build Coastguard Worker       }
1173*61046927SAndroid Build Coastguard Worker    } else if (callee->return_type != &glsl_type_builtin_void) {
1174*61046927SAndroid Build Coastguard Worker       printf("ir_call has non-void callee but no return storage\n");
1175*61046927SAndroid Build Coastguard Worker       abort();
1176*61046927SAndroid Build Coastguard Worker    }
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker    const exec_node *formal_param_node = callee->parameters.get_head_raw();
1179*61046927SAndroid Build Coastguard Worker    const exec_node *actual_param_node = ir->actual_parameters.get_head_raw();
1180*61046927SAndroid Build Coastguard Worker    while (true) {
1181*61046927SAndroid Build Coastguard Worker       if (formal_param_node->is_tail_sentinel()
1182*61046927SAndroid Build Coastguard Worker           != actual_param_node->is_tail_sentinel()) {
1183*61046927SAndroid Build Coastguard Worker          printf("ir_call has the wrong number of parameters:\n");
1184*61046927SAndroid Build Coastguard Worker          goto dump_ir;
1185*61046927SAndroid Build Coastguard Worker       }
1186*61046927SAndroid Build Coastguard Worker       if (formal_param_node->is_tail_sentinel()) {
1187*61046927SAndroid Build Coastguard Worker          break;
1188*61046927SAndroid Build Coastguard Worker       }
1189*61046927SAndroid Build Coastguard Worker       const ir_variable *formal_param
1190*61046927SAndroid Build Coastguard Worker          = (const ir_variable *) formal_param_node;
1191*61046927SAndroid Build Coastguard Worker       const ir_rvalue *actual_param
1192*61046927SAndroid Build Coastguard Worker          = (const ir_rvalue *) actual_param_node;
1193*61046927SAndroid Build Coastguard Worker       if (formal_param->type != actual_param->type) {
1194*61046927SAndroid Build Coastguard Worker          printf("ir_call parameter type mismatch:\n");
1195*61046927SAndroid Build Coastguard Worker          goto dump_ir;
1196*61046927SAndroid Build Coastguard Worker       }
1197*61046927SAndroid Build Coastguard Worker       if (formal_param->data.mode == ir_var_function_out
1198*61046927SAndroid Build Coastguard Worker           || formal_param->data.mode == ir_var_function_inout) {
1199*61046927SAndroid Build Coastguard Worker          if (!actual_param->is_lvalue()) {
1200*61046927SAndroid Build Coastguard Worker             printf("ir_call out/inout parameters must be lvalues:\n");
1201*61046927SAndroid Build Coastguard Worker             goto dump_ir;
1202*61046927SAndroid Build Coastguard Worker          }
1203*61046927SAndroid Build Coastguard Worker       }
1204*61046927SAndroid Build Coastguard Worker       formal_param_node = formal_param_node->next;
1205*61046927SAndroid Build Coastguard Worker       actual_param_node = actual_param_node->next;
1206*61046927SAndroid Build Coastguard Worker    }
1207*61046927SAndroid Build Coastguard Worker 
1208*61046927SAndroid Build Coastguard Worker    return visit_continue;
1209*61046927SAndroid Build Coastguard Worker 
1210*61046927SAndroid Build Coastguard Worker dump_ir:
1211*61046927SAndroid Build Coastguard Worker    ir->print();
1212*61046927SAndroid Build Coastguard Worker    printf("callee:\n");
1213*61046927SAndroid Build Coastguard Worker    callee->print();
1214*61046927SAndroid Build Coastguard Worker    abort();
1215*61046927SAndroid Build Coastguard Worker    return visit_stop;
1216*61046927SAndroid Build Coastguard Worker }
1217*61046927SAndroid Build Coastguard Worker 
1218*61046927SAndroid Build Coastguard Worker void
validate_ir(ir_instruction * ir,void * data)1219*61046927SAndroid Build Coastguard Worker ir_validate::validate_ir(ir_instruction *ir, void *data)
1220*61046927SAndroid Build Coastguard Worker {
1221*61046927SAndroid Build Coastguard Worker    struct set *ir_set = (struct set *) data;
1222*61046927SAndroid Build Coastguard Worker 
1223*61046927SAndroid Build Coastguard Worker    if (_mesa_set_search(ir_set, ir)) {
1224*61046927SAndroid Build Coastguard Worker       printf("Instruction node present twice in ir tree:\n");
1225*61046927SAndroid Build Coastguard Worker       ir->print();
1226*61046927SAndroid Build Coastguard Worker       printf("\n");
1227*61046927SAndroid Build Coastguard Worker       abort();
1228*61046927SAndroid Build Coastguard Worker    }
1229*61046927SAndroid Build Coastguard Worker    _mesa_set_add(ir_set, ir);
1230*61046927SAndroid Build Coastguard Worker }
1231*61046927SAndroid Build Coastguard Worker 
1232*61046927SAndroid Build Coastguard Worker static void
check_node_type(ir_instruction * ir,void * data)1233*61046927SAndroid Build Coastguard Worker check_node_type(ir_instruction *ir, void *data)
1234*61046927SAndroid Build Coastguard Worker {
1235*61046927SAndroid Build Coastguard Worker    (void) data;
1236*61046927SAndroid Build Coastguard Worker 
1237*61046927SAndroid Build Coastguard Worker    if (ir->ir_type >= ir_type_max) {
1238*61046927SAndroid Build Coastguard Worker       printf("Instruction node with unset type\n");
1239*61046927SAndroid Build Coastguard Worker       ir->print(); printf("\n");
1240*61046927SAndroid Build Coastguard Worker    }
1241*61046927SAndroid Build Coastguard Worker    ir_rvalue *value = ir->as_rvalue();
1242*61046927SAndroid Build Coastguard Worker    if (value != NULL)
1243*61046927SAndroid Build Coastguard Worker       assert(value->type != &glsl_type_builtin_error);
1244*61046927SAndroid Build Coastguard Worker }
1245*61046927SAndroid Build Coastguard Worker 
1246*61046927SAndroid Build Coastguard Worker void
validate_ir_tree(exec_list * instructions)1247*61046927SAndroid Build Coastguard Worker validate_ir_tree(exec_list *instructions)
1248*61046927SAndroid Build Coastguard Worker {
1249*61046927SAndroid Build Coastguard Worker    /* We shouldn't have any reason to validate IR in a release build,
1250*61046927SAndroid Build Coastguard Worker     * and it's half composed of assert()s anyway which wouldn't do
1251*61046927SAndroid Build Coastguard Worker     * anything.
1252*61046927SAndroid Build Coastguard Worker     */
1253*61046927SAndroid Build Coastguard Worker #if !MESA_DEBUG
1254*61046927SAndroid Build Coastguard Worker    if (!debug_get_bool_option("GLSL_VALIDATE", false))
1255*61046927SAndroid Build Coastguard Worker       return;
1256*61046927SAndroid Build Coastguard Worker #endif
1257*61046927SAndroid Build Coastguard Worker    ir_validate v;
1258*61046927SAndroid Build Coastguard Worker 
1259*61046927SAndroid Build Coastguard Worker    v.run(instructions);
1260*61046927SAndroid Build Coastguard Worker 
1261*61046927SAndroid Build Coastguard Worker    foreach_in_list(ir_instruction, ir, instructions) {
1262*61046927SAndroid Build Coastguard Worker       visit_tree(ir, check_node_type, NULL);
1263*61046927SAndroid Build Coastguard Worker    }
1264*61046927SAndroid Build Coastguard Worker }
1265