ac/nir: Handle const array offsets in get_deref_offset()
authorConnor Abbott <cwabbott0@gmail.com>
Tue, 20 Aug 2019 10:31:55 +0000 (12:31 +0200)
committerConnor Abbott <cwabbott0@gmail.com>
Fri, 23 Aug 2019 09:05:31 +0000 (11:05 +0200)
Some users of this function (e.g. GS inputs) currently only work with
constant offsets. We got lucky since all the tests used an array index
of 0, so the non-constant part was always 0. But we still need to handle
this.

This doesn't fix any CTS test, but was noticed while debugging one.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/amd/common/ac_nir_to_llvm.c

index 0b06290f58abb1385e4a29e8c9d04ea19cb40e9a..e6795bac97a6f594dbcac904c83658f769ed02b4 100644 (file)
@@ -1939,12 +1939,17 @@ get_deref_offset(struct ac_nir_context *ctx, nir_deref_instr *instr,
                        }
                } else if(path.path[idx_lvl]->deref_type == nir_deref_type_array) {
                        unsigned size = glsl_count_attribute_slots(path.path[idx_lvl]->type, vs_in);
-                       LLVMValueRef array_off = LLVMBuildMul(ctx->ac.builder, LLVMConstInt(ctx->ac.i32, size, 0),
-                                                             get_src(ctx, path.path[idx_lvl]->arr.index), "");
-                       if (offset)
-                               offset = LLVMBuildAdd(ctx->ac.builder, offset, array_off, "");
-                       else
-                               offset = array_off;
+                       if (nir_src_is_const(path.path[idx_lvl]->arr.index)) {
+                               const_offset += size *
+                                       nir_src_as_uint(path.path[idx_lvl]->arr.index);
+                       } else {
+                               LLVMValueRef array_off = LLVMBuildMul(ctx->ac.builder, LLVMConstInt(ctx->ac.i32, size, 0),
+                                                                     get_src(ctx, path.path[idx_lvl]->arr.index), "");
+                               if (offset)
+                                       offset = LLVMBuildAdd(ctx->ac.builder, offset, array_off, "");
+                               else
+                                       offset = array_off;
+                       }
                } else
                        unreachable("Uhandled deref type in get_deref_instr_offset");
        }