freedreno/ir3/cf: handle multiple cov's properly
authorRob Clark <robdclark@chromium.org>
Sat, 16 May 2020 00:12:25 +0000 (17:12 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 19 May 2020 16:06:17 +0000 (16:06 +0000)
There can be multiple (for ex.) f32f16's from a single source, in
particular appearing in different blocks.  We need to update all uses
of the src which had conversion folded in, not all the uses of the
individual cov.  Also, to avoid invalidating the ssa use info that was
gathered at the beginning of the pass, don't actually eliminate the
cov, but instead change it to a simple mov that the cp pass can gobble
up.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5048>

src/freedreno/ir3/ir3_cf.c

index ee717187a99bc5ea0a01d6e5f21f8fb524b954e1..c1dc5385d361dace2e4e611a1d6e828770dc3adb 100644 (file)
@@ -65,14 +65,24 @@ all_uses_fp16_conv(struct ir3_instruction *conv_src)
        return true;
 }
 
+/* For an instruction which has a conversion folded in, re-write the
+ * uses of *all* conv's that used that src to be a simple mov that
+ * cp can eliminate.  This avoids invalidating the SSA uses, it just
+ * shifts the use to a simple mov.
+ */
 static void
-rewrite_uses(struct ir3_instruction *conv, struct ir3_instruction *replace)
+rewrite_src_uses(struct ir3_instruction *src)
 {
-       foreach_ssa_use (use, conv) {
-               foreach_ssa_src_n (src, n, use) {
-                       if (src == conv)
-                               use->regs[n]->instr = replace;
+       foreach_ssa_use (use, src) {
+               assert(is_fp16_conv(use));
+
+               if (is_half(src)) {
+                       use->regs[1]->flags |= IR3_REG_HALF;
+               } else {
+                       use->regs[1]->flags &= ~IR3_REG_HALF;
                }
+
+               use->cat1.src_type = use->cat1.dst_type;
        }
 }
 
@@ -113,6 +123,7 @@ try_conversion_folding(struct ir3_instruction *conv)
                if (src->cat1.dst_type != src->cat1.src_type &&
                        conv->cat1.src_type != src->cat1.dst_type)
                        return false;
+               break;
        default:
                break;
        }
@@ -137,13 +148,13 @@ try_conversion_folding(struct ir3_instruction *conv)
                }
        }
 
-       if (conv->regs[0]->flags & IR3_REG_HALF) {
+       if (is_half(conv)) {
                src->regs[0]->flags |= IR3_REG_HALF;
        } else {
                src->regs[0]->flags &= ~IR3_REG_HALF;
        }
 
-       rewrite_uses(conv, src);
+       rewrite_src_uses(src);
 
        return true;
 }
@@ -157,7 +168,7 @@ ir3_cf(struct ir3 *ir)
        ir3_find_ssa_uses(ir, mem_ctx, false);
 
        foreach_block (block, &ir->block_list) {
-               foreach_instr_safe (instr, &block->instr_list) {
+               foreach_instr (instr, &block->instr_list) {
                        progress |= try_conversion_folding(instr);
                }
        }