From: Nicolai Hähnle <nicolai.haeh...@amd.com>

This simplifies a bunch of places that no longer need special treatment
of value_count == 1. We rely on LLVM to optimize away the 1-element vector
types.

This fixes a bunch of bugs where 1-element arrays are indexed indirectly.
---
 src/amd/common/ac_llvm_build.c  |  7 ++++---
 src/amd/common/ac_llvm_build.h  |  3 ++-
 src/amd/common/ac_nir_to_llvm.c | 22 +++++++---------------
 3 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 9d78b12..0a3cc8a 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -175,27 +175,28 @@ void ac_build_type_name_for_intr(LLVMTypeRef type, char 
*buf, unsigned bufsize)
                snprintf(buf, bufsize, "f64");
                break;
        }
 }
 
 LLVMValueRef
 ac_build_gather_values_extended(struct ac_llvm_context *ctx,
                                LLVMValueRef *values,
                                unsigned value_count,
                                unsigned value_stride,
-                               bool load)
+                               bool load,
+                               bool always_vector)
 {
        LLVMBuilderRef builder = ctx->builder;
        LLVMValueRef vec = NULL;
        unsigned i;
 
-       if (value_count == 1) {
+       if (value_count == 1 && !always_vector) {
                if (load)
                        return LLVMBuildLoad(builder, values[0], "");
                return values[0];
        } else if (!value_count)
                unreachable("value_count is 0");
 
        for (i = 0; i < value_count; i++) {
                LLVMValueRef value = values[i * value_stride];
                if (load)
                        value = LLVMBuildLoad(builder, value, "");
@@ -206,21 +207,21 @@ ac_build_gather_values_extended(struct ac_llvm_context 
*ctx,
                vec = LLVMBuildInsertElement(builder, vec, value, index, "");
        }
        return vec;
 }
 
 LLVMValueRef
 ac_build_gather_values(struct ac_llvm_context *ctx,
                       LLVMValueRef *values,
                       unsigned value_count)
 {
-       return ac_build_gather_values_extended(ctx, values, value_count, 1, 
false);
+       return ac_build_gather_values_extended(ctx, values, value_count, 1, 
false, false);
 }
 
 LLVMValueRef
 ac_build_fdiv(struct ac_llvm_context *ctx,
              LLVMValueRef num,
              LLVMValueRef den)
 {
        LLVMValueRef ret = LLVMBuildFDiv(ctx->builder, num, den, "");
 
        if (!LLVMIsConstant(ret))
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index b9aeacd..9ad13cc 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -72,21 +72,22 @@ ac_build_intrinsic(struct ac_llvm_context *ctx, const char 
*name,
                   LLVMTypeRef return_type, LLVMValueRef *params,
                   unsigned param_count, unsigned attrib_mask);
 
 void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned 
bufsize);
 
 LLVMValueRef
 ac_build_gather_values_extended(struct ac_llvm_context *ctx,
                                LLVMValueRef *values,
                                unsigned value_count,
                                unsigned value_stride,
-                               bool load);
+                               bool load,
+                               bool always_vector);
 LLVMValueRef
 ac_build_gather_values(struct ac_llvm_context *ctx,
                       LLVMValueRef *values,
                       unsigned value_count);
 
 LLVMValueRef
 ac_build_fdiv(struct ac_llvm_context *ctx,
              LLVMValueRef num,
              LLVMValueRef den);
 
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index f428d7c..e24ad65 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1032,25 +1032,20 @@ static LLVMValueRef trim_vector(struct ac_llvm_context 
*ctx,
 static void
 build_store_values_extended(struct ac_llvm_context *ac,
                             LLVMValueRef *values,
                             unsigned value_count,
                             unsigned value_stride,
                             LLVMValueRef vec)
 {
        LLVMBuilderRef builder = ac->builder;
        unsigned i;
 
-       if (value_count == 1) {
-               LLVMBuildStore(builder, vec, values[0]);
-               return;
-       }
-
        for (i = 0; i < value_count; i++) {
                LLVMValueRef ptr = values[i * value_stride];
                LLVMValueRef index = LLVMConstInt(ac->i32, i, false);
                LLVMValueRef value = LLVMBuildExtractElement(builder, vec, 
index, "");
                LLVMBuildStore(builder, value, ptr);
        }
 }
 
 static LLVMTypeRef get_def_type(struct ac_nir_context *ctx,
                                 const nir_ssa_def *def)
@@ -2918,58 +2913,58 @@ static LLVMValueRef visit_load_var(struct 
ac_nir_context *ctx,
                        return load_gs_input(ctx->nctx, instr);
                }
                for (unsigned chan = 0; chan < ve; chan++) {
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
                                                instr->variables[0]->var->type,
                                                ctx->stage == 
MESA_SHADER_VERTEX);
                                count -= chan / 4;
                                LLVMValueRef tmp_vec = 
ac_build_gather_values_extended(
                                                &ctx->ac, ctx->abi->inputs + 
idx + chan, count,
-                                               4, false);
+                                               4, false, true);
 
                                values[chan] = 
LLVMBuildExtractElement(ctx->ac.builder,
                                                                       tmp_vec,
                                                                       
indir_index, "");
                        } else
                                values[chan] = ctx->abi->inputs[idx + chan + 
const_index * 4];
                }
                break;
        case nir_var_local:
                for (unsigned chan = 0; chan < ve; chan++) {
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
                                        instr->variables[0]->var->type, false);
                                count -= chan / 4;
                                LLVMValueRef tmp_vec = 
ac_build_gather_values_extended(
                                                &ctx->ac, ctx->locals + idx + 
chan, count,
-                                               4, true);
+                                               4, true, true);
 
                                values[chan] = 
LLVMBuildExtractElement(ctx->ac.builder,
                                                                       tmp_vec,
                                                                       
indir_index, "");
                        } else {
                                values[chan] = LLVMBuildLoad(ctx->ac.builder, 
ctx->locals[idx + chan + const_index * 4], "");
                        }
                }
                break;
        case nir_var_shader_out:
                if (ctx->stage == MESA_SHADER_TESS_CTRL)
                        return load_tcs_output(ctx->nctx, instr);
                for (unsigned chan = 0; chan < ve; chan++) {
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
                                                instr->variables[0]->var->type, 
false);
                                count -= chan / 4;
                                LLVMValueRef tmp_vec = 
ac_build_gather_values_extended(
                                                &ctx->ac, ctx->outputs + idx + 
chan, count,
-                                               4, true);
+                                               4, true, true);
 
                                values[chan] = 
LLVMBuildExtractElement(ctx->ac.builder,
                                                                       tmp_vec,
                                                                       
indir_index, "");
                        } else {
                                values[chan] = LLVMBuildLoad(ctx->ac.builder,
                                                     ctx->outputs[idx + chan + 
const_index * 4],
                                                     "");
                        }
                }
@@ -3041,27 +3036,24 @@ visit_store_var(struct ac_nir_context *ctx,
                        value = llvm_extract_elem(&ctx->ac, src, chan);
 
                        if (instr->variables[0]->var->data.compact)
                                stride = 1;
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
                                                instr->variables[0]->var->type, 
false);
                                count -= chan / 4;
                                LLVMValueRef tmp_vec = 
ac_build_gather_values_extended(
                                                &ctx->ac, ctx->outputs + idx + 
chan, count,
-                                               stride, true);
+                                               stride, true, true);
 
-                               if (get_llvm_num_components(tmp_vec) > 1) {
-                                       tmp_vec = 
LLVMBuildInsertElement(ctx->ac.builder, tmp_vec,
-                                                                        value, 
indir_index, "");
-                               } else
-                                       tmp_vec = value;
+                               tmp_vec = 
LLVMBuildInsertElement(ctx->ac.builder, tmp_vec,
+                                                                value, 
indir_index, "");
                                build_store_values_extended(&ctx->ac, 
ctx->outputs + idx + chan,
                                                            count, stride, 
tmp_vec);
 
                        } else {
                                temp_ptr = ctx->outputs[idx + chan + 
const_index * stride];
 
                                LLVMBuildStore(ctx->ac.builder, value, 
temp_ptr);
                        }
                }
                break;
@@ -3070,21 +3062,21 @@ visit_store_var(struct ac_nir_context *ctx,
                        if (!(writemask & (1 << chan)))
                                continue;
 
                        value = llvm_extract_elem(&ctx->ac, src, chan);
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
                                        instr->variables[0]->var->type, false);
                                count -= chan / 4;
                                LLVMValueRef tmp_vec = 
ac_build_gather_values_extended(
                                        &ctx->ac, ctx->locals + idx + chan, 
count,
-                                       4, true);
+                                       4, true, true);
 
                                tmp_vec = 
LLVMBuildInsertElement(ctx->ac.builder, tmp_vec,
                                                                 value, 
indir_index, "");
                                build_store_values_extended(&ctx->ac, 
ctx->locals + idx + chan,
                                                            count, 4, tmp_vec);
                        } else {
                                temp_ptr = ctx->locals[idx + chan + const_index 
* 4];
 
                                LLVMBuildStore(ctx->ac.builder, value, 
temp_ptr);
                        }
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to