if (new_shift < -31 || new_shift > 31)
return NULL;
- b->cursor = nir_before_instr(&alu_instr->instr);
-
/* Add or substract shift depending on the final direction (SHR vs. SHL). */
if (shift * direction < 0)
shift_ssa = nir_isub(b, shift_ssa, nir_imm_int(b, abs(shift)));
nir_ssa_def *shift_ssa;
nir_ssa_def *new_offset = NULL;
+ b->cursor = nir_after_instr(&alu->instr);
+
+ /* the first src could be something like ssa_18.x, but we only want
+ * the single component. Otherwise the ishl/ishr/ushr could turn
+ * into a vec4 operation:
+ */
+ nir_ssa_def *src0 = nir_mov_alu(b, alu->src[0], 1);
+
switch (alu->op) {
case nir_op_ishl:
shift_ssa = check_and_propagate_bit_shift32(b, alu, 1, shift);
if (shift_ssa)
- new_offset = nir_ishl(b, alu->src[0].src.ssa, shift_ssa);
+ new_offset = nir_ishl(b, src0, shift_ssa);
break;
case nir_op_ishr:
shift_ssa = check_and_propagate_bit_shift32(b, alu, -1, shift);
if (shift_ssa)
- new_offset = nir_ishr(b, alu->src[0].src.ssa, shift_ssa);
+ new_offset = nir_ishr(b, src0, shift_ssa);
break;
case nir_op_ushr:
shift_ssa = check_and_propagate_bit_shift32(b, alu, -1, shift);
if (shift_ssa)
- new_offset = nir_ushr(b, alu->src[0].src.ssa, shift_ssa);
+ new_offset = nir_ushr(b, src0, shift_ssa);
break;
default:
return NULL;