freedreno/ir3: use stg.a/ldg.a only if offset is reg or doesn't fit
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Fri, 8 Oct 2021 15:36:43 +0000 (18:36 +0300)
committerMarge Bot <eric+marge@anholt.net>
Thu, 21 Oct 2021 18:59:57 +0000 (18:59 +0000)
Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13300>

src/freedreno/ir3/ir3_a6xx.c

index ae97923..8138fba 100644 (file)
@@ -376,11 +376,22 @@ emit_intrinsic_load_global_ir3(struct ir3_context *ctx,
    addr = ir3_collect(b, ir3_get_src(ctx, &intr->src[0])[0],
                       ir3_get_src(ctx, &intr->src[0])[1]);
 
-   offset = ir3_get_src(ctx, &intr->src[1])[0];
+   struct ir3_instruction *load;
+
+   bool const_offset_in_bounds = nir_src_is_const(intr->src[1]) &&
+                                 nir_src_as_int(intr->src[1]) < (1 << 13) &&
+                                 nir_src_as_int(intr->src[1]) > -(1 << 13);
+
+   if (const_offset_in_bounds) {
+      load = ir3_LDG(b, addr, 0, create_immed(b, nir_src_as_int(intr->src[1])),
+                     0, create_immed(b, dest_components), 0);
+   } else {
+      offset = ir3_get_src(ctx, &intr->src[1])[0];
+      load =
+         ir3_LDG_A(b, addr, 0, offset, 0, create_immed(b, 0), 0,
+                   create_immed(b, 0), 0, create_immed(b, dest_components), 0);
+   }
 
-   struct ir3_instruction *load =
-      ir3_LDG_A(b, addr, 0, offset, 0, create_immed(b, 0), 0,
-                create_immed(b, 0), 0, create_immed(b, dest_components), 0);
    load->cat6.type = TYPE_U32;
    load->dsts[0]->wrmask = MASK(dest_components);
 
@@ -401,13 +412,26 @@ emit_intrinsic_store_global_ir3(struct ir3_context *ctx,
    addr = ir3_collect(b, ir3_get_src(ctx, &intr->src[1])[0],
                       ir3_get_src(ctx, &intr->src[1])[1]);
 
-   offset = ir3_get_src(ctx, &intr->src[2])[0];
-
    value = ir3_create_collect(b, ir3_get_src(ctx, &intr->src[0]), ncomp);
 
-   struct ir3_instruction *stg =
-      ir3_STG_A(b, addr, 0, offset, 0, create_immed(b, 0), 0,
-                create_immed(b, 0), 0, value, 0, create_immed(b, ncomp), 0);
+   struct ir3_instruction *stg;
+
+   bool const_offset_in_bounds = nir_src_is_const(intr->src[2]) &&
+                                 nir_src_as_int(intr->src[2]) < (1 << 13) &&
+                                 nir_src_as_int(intr->src[2]) > -(1 << 13);
+
+   if (const_offset_in_bounds) {
+      stg = ir3_STG(b, addr, 0,
+                    create_immed(b, nir_src_as_int(intr->src[2])), 0,
+                    value, 0,
+                    create_immed(b, ncomp), 0);
+   } else {
+      offset = ir3_get_src(ctx, &intr->src[2])[0];
+      stg =
+         ir3_STG_A(b, addr, 0, offset, 0, create_immed(b, 0), 0,
+                   create_immed(b, 0), 0, value, 0, create_immed(b, ncomp), 0);
+   }
+
    stg->cat6.type = TYPE_U32;
    stg->cat6.iim_val = 1;