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