freedreno/ir3: handle multi component alu src when propagating shifts
authorRob Clark <robdclark@chromium.org>
Wed, 9 Oct 2019 16:47:13 +0000 (09:47 -0700)
committerRob Clark <robdclark@gmail.com>
Thu, 10 Oct 2019 23:12:05 +0000 (23:12 +0000)
Signed-off-by: Rob Clark <robdclark@chromium.org>
src/freedreno/ir3/ir3_nir_lower_io_offsets.c

index 5c64a864f290ec710c7d4b6619634cb36b0e53b6..72a7efe5327c01d7972567f5a630b0c454e45e4c 100644 (file)
@@ -112,8 +112,6 @@ check_and_propagate_bit_shift32(nir_builder *b, nir_alu_instr *alu_instr,
        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)));
@@ -134,21 +132,29 @@ ir3_nir_try_propagate_bit_shift(nir_builder *b, nir_ssa_def *offset, int32_t shi
        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;