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) == (((reg)->flags & IR3_REG_HALF) ? 16 : 32)) 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 (n > 0) { 203 validate_assert(ctx, (last_reg->flags & IR3_REG_HALF) == 204 (reg->flags & IR3_REG_HALF)); 205 } 206 207 last_reg = reg; 208 } 209 210 for (unsigned i = 0; i < instr->dsts_count; i++) { 211 struct ir3_register *reg = instr->dsts[i]; 212 213 validate_dst(ctx, instr, reg); 214 } 215 216 _mesa_set_add(ctx->defs, instr); 217 218 /* Check that src/dst types match the register types, and for 219 * instructions that have different opcodes depending on type, 220 * that the opcodes are correct. 221 */ 222 switch (opc_cat(instr->opc)) { 223 case 1: /* move instructions */ 224 if (instr->opc == OPC_MOVMSK || instr->opc == OPC_BALLOT_MACRO) { 225 validate_assert(ctx, instr->dsts_count == 1); 226 validate_assert(ctx, instr->dsts[0]->flags & IR3_REG_SHARED); 227 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF)); 228 validate_assert( 229 ctx, util_is_power_of_two_or_zero(instr->dsts[0]->wrmask + 1)); 230 } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO || 231 instr->opc == OPC_READ_FIRST_MACRO || 232 instr->opc == OPC_READ_COND_MACRO) { 233 /* nothing yet */ 234 } else if (instr->opc == OPC_ELECT_MACRO) { 235 validate_assert(ctx, instr->dsts_count == 1); 236 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_SHARED)); 237 } else { 238 foreach_dst (dst, instr) 239 validate_reg_size(ctx, dst, instr->cat1.dst_type); 240 foreach_src (src, instr) { 241 if (!src->tied && src != instr->address) 242 validate_reg_size(ctx, src, instr->cat1.src_type); 243 } 244 245 switch (instr->opc) { 246 case OPC_SWZ: 247 validate_assert(ctx, instr->srcs_count == 2); 248 validate_assert(ctx, instr->dsts_count == 2); 249 break; 250 case OPC_GAT: 251 validate_assert(ctx, instr->srcs_count == 4); 252 validate_assert(ctx, instr->dsts_count == 1); 253 break; 254 case OPC_SCT: 255 validate_assert(ctx, instr->srcs_count == 1); 256 validate_assert(ctx, instr->dsts_count == 4); 257 break; 258 default: 259 break; 260 } 261 } 262 263 if (instr->opc != OPC_MOV) 264 validate_assert(ctx, !instr->address); 265 266 break; 267 case 3: 268 /* Validate that cat3 opc matches the src type. We've already checked 269 * that all the src regs are same type 270 */ 271 if (instr->srcs[0]->flags & IR3_REG_HALF) { 272 validate_assert(ctx, instr->opc == cat3_half_opc(instr->opc)); 273 } else { 274 validate_assert(ctx, instr->opc == cat3_full_opc(instr->opc)); 275 } 276 break; 277 case 4: 278 /* Validate that cat4 opc matches the dst type: */ 279 if (instr->dsts[0]->flags & IR3_REG_HALF) { 280 validate_assert(ctx, instr->opc == cat4_half_opc(instr->opc)); 281 } else { 282 validate_assert(ctx, instr->opc == cat4_full_opc(instr->opc)); 283 } 284 break; 285 case 5: 286 validate_reg_size(ctx, instr->dsts[0], instr->cat5.type); 287 break; 288 case 6: 289 switch (instr->opc) { 290 case OPC_RESINFO: 291 case OPC_RESFMT: 292 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type); 293 validate_reg_size(ctx, instr->srcs[0], instr->cat6.type); 294 break; 295 case OPC_L2G: 296 case OPC_G2L: 297 validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF)); 298 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 299 break; 300 case OPC_STG: 301 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 302 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 303 validate_reg_size(ctx, instr->srcs[2], instr->cat6.type); 304 validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF)); 305 break; 306 case OPC_STG_A: 307 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 308 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 309 validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF)); 310 validate_reg_size(ctx, instr->srcs[4], instr->cat6.type); 311 validate_assert(ctx, !(instr->srcs[5]->flags & IR3_REG_HALF)); 312 break; 313 case OPC_STL: 314 case OPC_STP: 315 case OPC_STLW: 316 case OPC_SPILL_MACRO: 317 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 318 validate_reg_size(ctx, instr->srcs[1], instr->cat6.type); 319 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 320 break; 321 case OPC_STIB: 322 if (instr->flags & IR3_INSTR_B) { 323 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 324 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 325 validate_reg_size(ctx, instr->srcs[2], instr->cat6.type); 326 } else { 327 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 328 validate_reg_size(ctx, instr->srcs[1], instr->cat6.type); 329 validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 330 } 331 break; 332 default: 333 validate_reg_size(ctx, instr->dsts[0], instr->cat6.type); 334 validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 335 if (instr->srcs_count > 1) 336 validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 337 break; 338 } 339 } 340 341 if (instr->opc == OPC_META_PARALLEL_COPY) { 342 foreach_src_n (src, n, instr) { 343 validate_assert(ctx, reg_class_flags(src) == 344 reg_class_flags(instr->dsts[n])); 345 } 346 } 347} 348 349static bool 350is_physical_successor(struct ir3_block *block, struct ir3_block *succ) 351{ 352 for (unsigned i = 0; i < ARRAY_SIZE(block->physical_successors); i++) 353 if (block->physical_successors[i] == succ) 354 return true; 355 return false; 356} 357 358void 359ir3_validate(struct ir3 *ir) 360{ 361#ifdef NDEBUG 362#define VALIDATE 0 363#else 364#define VALIDATE 1 365#endif 366 367 if (!VALIDATE) 368 return; 369 370 struct ir3_validate_ctx *ctx = ralloc_size(NULL, sizeof(*ctx)); 371 372 ctx->ir = ir; 373 ctx->defs = _mesa_pointer_set_create(ctx); 374 375 foreach_block (block, &ir->block_list) { 376 ctx->current_block = block; 377 ctx->current_instr = NULL; 378 379 /* We require that the first block does not have any predecessors, 380 * which allows us to assume that phi nodes and meta:input's do not 381 * appear in the same basic block. 382 */ 383 validate_assert( 384 ctx, block != ir3_start_block(ir) || block->predecessors_count == 0); 385 386 struct ir3_instruction *prev = NULL; 387 foreach_instr (instr, &block->instr_list) { 388 ctx->current_instr = instr; 389 if (instr->opc == OPC_META_PHI) { 390 /* phis must be the first in the block */ 391 validate_assert(ctx, prev == NULL || prev->opc == OPC_META_PHI); 392 validate_phi(ctx, instr); 393 } else { 394 validate_instr(ctx, instr); 395 } 396 prev = instr; 397 } 398 399 for (unsigned i = 0; i < 2; i++) { 400 if (block->successors[i]) { 401 validate_phi_src(ctx, block->successors[i], block); 402 403 ctx->current_instr = NULL; 404 405 /* Each logical successor should also be a physical successor: */ 406 validate_assert(ctx, is_physical_successor(block, block->successors[i])); 407 } 408 } 409 410 validate_assert(ctx, block->successors[0] || !block->successors[1]); 411 validate_assert(ctx, block->physical_successors[0] || !block->physical_successors[1]); 412 } 413 414 ralloc_free(ctx); 415} 416