nir: Use nir_src_copy instead of direct assignments.

If the source is an indirect register, there is ralloc'd data.  Copying
with a direct assignment will copy the pointer, but the data will still
belong to the old instruction's memory context.  Since we're lowering
and throwing away instructions, that could free the data by mistake.

Instead, use nir_src_copy, which properly handles this.

This is admittedly not a common case, so I think the bug is real,
but unlikely to be hit.

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
Kenneth Graunke 2017-07-17 21:08:42 -07:00
parent 57165f2ef8
commit 0320bb2c6c
3 changed files with 9 additions and 9 deletions

View file

@ -155,7 +155,7 @@ lower_instr(nir_intrinsic_instr *instr,
* instruction.
*/
for (unsigned i = 0; i < nir_intrinsic_infos[instr->intrinsic].num_srcs; i++)
new_instr->src[i + 1] = instr->src[i];
nir_src_copy(&new_instr->src[i + 1], &instr->src[i], new_instr);
if (instr->dest.is_ssa) {
nir_ssa_dest_init(&new_instr->instr, &new_instr->dest,

View file

@ -115,7 +115,7 @@ lower_instr(nir_intrinsic_instr *instr, unsigned ssbo_offset, nir_builder *b)
/* remapped to ssbo_atomic_add: { buffer_idx, offset, +1 } */
temp = nir_imm_int(b, +1);
new_instr->src[0] = nir_src_for_ssa(buffer);
new_instr->src[1] = instr->src[0];
nir_src_copy(&new_instr->src[1], &instr->src[0], new_instr);
new_instr->src[2] = nir_src_for_ssa(temp);
break;
case nir_intrinsic_atomic_counter_dec:
@ -123,21 +123,21 @@ lower_instr(nir_intrinsic_instr *instr, unsigned ssbo_offset, nir_builder *b)
/* NOTE semantic difference so we adjust the return value below */
temp = nir_imm_int(b, -1);
new_instr->src[0] = nir_src_for_ssa(buffer);
new_instr->src[1] = instr->src[0];
nir_src_copy(&new_instr->src[1], &instr->src[0], new_instr);
new_instr->src[2] = nir_src_for_ssa(temp);
break;
case nir_intrinsic_atomic_counter_read:
/* remapped to load_ssbo: { buffer_idx, offset } */
new_instr->src[0] = nir_src_for_ssa(buffer);
new_instr->src[1] = instr->src[0];
nir_src_copy(&new_instr->src[1], &instr->src[0], new_instr);
break;
default:
/* remapped to ssbo_atomic_x: { buffer_idx, offset, data, (compare)? } */
new_instr->src[0] = nir_src_for_ssa(buffer);
new_instr->src[1] = instr->src[0];
new_instr->src[2] = instr->src[1];
nir_src_copy(&new_instr->src[1], &instr->src[0], new_instr);
nir_src_copy(&new_instr->src[2], &instr->src[1], new_instr);
if (op == nir_intrinsic_ssbo_atomic_comp_swap)
new_instr->src[3] = instr->src[2];
nir_src_copy(&new_instr->src[3], &instr->src[2], new_instr);
break;
}

View file

@ -49,7 +49,7 @@ lower_load_input_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
nir_intrinsic_set_base(chan_intr, nir_intrinsic_base(intr));
nir_intrinsic_set_component(chan_intr, nir_intrinsic_component(intr) + i);
/* offset */
chan_intr->src[0] = intr->src[0];
nir_src_copy(&chan_intr->src[0], &intr->src[0], chan_intr);
nir_builder_instr_insert(b, &chan_intr->instr);
@ -84,7 +84,7 @@ lower_store_output_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
/* value */
chan_intr->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
/* offset */
chan_intr->src[1] = intr->src[1];
nir_src_copy(&chan_intr->src[1], &intr->src[1], chan_intr);
nir_builder_instr_insert(b, &chan_intr->instr);
}