diff --git a/src/intel/compiler/brw_eu_defines.h b/src/intel/compiler/brw_eu_defines.h index 66e6c53c2b7..933037c4df3 100644 --- a/src/intel/compiler/brw_eu_defines.h +++ b/src/intel/compiler/brw_eu_defines.h @@ -322,6 +322,14 @@ enum opcode { */ SHADER_OPCODE_SEND, + /** + * An "undefined" write which does nothing but indicates to liveness that + * we don't care about any values in the register which predate this + * instruction. Used to prevent partial writes from causing issues with + * live ranges. + */ + SHADER_OPCODE_UNDEF, + /** * Texture sampling opcodes. * diff --git a/src/intel/compiler/brw_fs_builder.h b/src/intel/compiler/brw_fs_builder.h index a69e3c6ae80..9655c2ef554 100644 --- a/src/intel/compiler/brw_fs_builder.h +++ b/src/intel/compiler/brw_fs_builder.h @@ -706,6 +706,17 @@ namespace brw { return inst; } + instruction * + UNDEF(const dst_reg &dst) const + { + assert(dst.file == VGRF); + instruction *inst = emit(SHADER_OPCODE_UNDEF, + retype(dst, BRW_REGISTER_TYPE_UD)); + inst->size_written = shader->alloc.sizes[dst.nr] * REG_SIZE; + + return inst; + } + backend_shader *shader; private: diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index f91c857678a..7adc8a7938b 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -1653,6 +1653,9 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) struct disasm_info *disasm_info = disasm_initialize(devinfo, cfg); foreach_block_and_inst (block, fs_inst, inst, cfg) { + if (inst->opcode == SHADER_OPCODE_UNDEF) + continue; + struct brw_reg src[4], dst; unsigned int last_insn_offset = p->next_insn_offset; bool multiple_instructions_emitted = false; diff --git a/src/intel/compiler/brw_fs_lower_regioning.cpp b/src/intel/compiler/brw_fs_lower_regioning.cpp index a76fd262a10..98699c38d84 100644 --- a/src/intel/compiler/brw_fs_lower_regioning.cpp +++ b/src/intel/compiler/brw_fs_lower_regioning.cpp @@ -288,7 +288,9 @@ namespace { const unsigned stride = type_sz(inst->dst.type) * inst->dst.stride <= type_sz(type) ? 1 : type_sz(inst->dst.type) * inst->dst.stride / type_sz(type); - const fs_reg tmp = horiz_stride(ibld.vgrf(type, stride), stride); + fs_reg tmp = ibld.vgrf(type, stride); + ibld.UNDEF(tmp); + tmp = horiz_stride(tmp, stride); /* Emit a MOV taking care of all the destination modifiers. */ fs_inst *mov = ibld.at(block, inst->next).MOV(inst->dst, tmp); @@ -329,8 +331,9 @@ namespace { const unsigned stride = type_sz(inst->dst.type) * inst->dst.stride / type_sz(inst->src[i].type); assert(stride > 0); - const fs_reg tmp = horiz_stride(ibld.vgrf(inst->src[i].type, stride), - stride); + fs_reg tmp = ibld.vgrf(inst->src[i].type, stride); + ibld.UNDEF(tmp); + tmp = horiz_stride(tmp, stride); /* Emit a series of 32-bit integer copies with any source modifiers * cleaned up (because their semantics are dependent on the type). @@ -377,8 +380,9 @@ namespace { const unsigned stride = required_dst_byte_stride(inst) / type_sz(inst->dst.type); assert(stride > 0); - const fs_reg tmp = horiz_stride(ibld.vgrf(inst->dst.type, stride), - stride); + fs_reg tmp = ibld.vgrf(inst->dst.type, stride); + ibld.UNDEF(tmp); + tmp = horiz_stride(tmp, stride); /* Emit a series of 32-bit integer copies from the temporary into the * original destination. diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index 77b131272ca..eef21294d07 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -1951,6 +1951,7 @@ fs_visitor::get_nir_dest(const nir_dest &dest) BRW_REGISTER_TYPE_F); nir_ssa_values[dest.ssa.index] = bld.vgrf(reg_type, dest.ssa.num_components); + bld.UNDEF(nir_ssa_values[dest.ssa.index]); return nir_ssa_values[dest.ssa.index]; } else { /* We don't handle indirects on locals */ diff --git a/src/intel/compiler/brw_shader.cpp b/src/intel/compiler/brw_shader.cpp index 1f98bd08224..2061afc1c24 100644 --- a/src/intel/compiler/brw_shader.cpp +++ b/src/intel/compiler/brw_shader.cpp @@ -217,6 +217,9 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op) case SHADER_OPCODE_SEND: return "send"; + case SHADER_OPCODE_UNDEF: + return "undef"; + case SHADER_OPCODE_TEX: return "tex"; case SHADER_OPCODE_TEX_LOGICAL: