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