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