[Mesa-dev] [PATCH 06/24] ac: replace SI.export with amdgcn.exp.*

Marek Olšák maraeo at gmail.com
Sat Feb 25 23:58:04 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/amd/common/ac_llvm_build.c           | 31 +++++++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_shader.c |  8 +++++---
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index fae5510..bd1b63d 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -884,20 +884,51 @@ LLVMValueRef ac_emit_clamp(struct ac_llvm_context *ctx, LLVMValueRef value)
 
 	return ac_emit_llvm_intrinsic(ctx, intr, ctx->f32, args, 3,
 				      AC_FUNC_ATTR_READNONE |
 				      AC_FUNC_ATTR_LEGACY);
 }
 
 void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
 {
 	LLVMValueRef args[9];
 
+	if (HAVE_LLVM >= 0x0500) {
+		args[0] = LLVMConstInt(ctx->i32, a->target, 0);
+		args[1] = LLVMConstInt(ctx->i32, a->enabled_channels, 0);
+
+		if (a->compr) {
+			LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx->context);
+			LLVMTypeRef v2i16 = LLVMVectorType(i16, 2);
+
+			args[2] = LLVMBuildBitCast(ctx->builder, a->out[0],
+						   v2i16, "");
+			args[3] = LLVMBuildBitCast(ctx->builder, a->out[1],
+						   v2i16, "");
+			args[4] = LLVMConstInt(ctx->i1, a->done, 0);
+			args[5] = LLVMConstInt(ctx->i1, a->valid_mask, 0);
+
+			ac_emit_llvm_intrinsic(ctx, "llvm.amdgcn.exp.compr.v2i16",
+					       ctx->voidt, args, 6, 0);
+		} else {
+			args[2] = a->out[0];
+			args[3] = a->out[1];
+			args[4] = a->out[2];
+			args[5] = a->out[3];
+			args[6] = LLVMConstInt(ctx->i1, a->done, 0);
+			args[7] = LLVMConstInt(ctx->i1, a->valid_mask, 0);
+
+			ac_emit_llvm_intrinsic(ctx, "llvm.amdgcn.exp.f32",
+					       ctx->voidt, args, 8, 0);
+		}
+		return;
+	}
+
 	args[0] = LLVMConstInt(ctx->i32, a->enabled_channels, 0);
 	args[1] = LLVMConstInt(ctx->i32, a->valid_mask, 0);
 	args[2] = LLVMConstInt(ctx->i32, a->done, 0);
 	args[3] = LLVMConstInt(ctx->i32, a->target, 0);
 	args[4] = LLVMConstInt(ctx->i32, a->compr, 0);
 	memcpy(args + 5, a->out, sizeof(a->out[0]) * 4);
 
 	ac_emit_llvm_intrinsic(ctx, "llvm.SI.export", ctx->voidt, args, 9,
 			       AC_FUNC_ATTR_LEGACY);
 }
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 61e05d5..8c07b4f 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6485,21 +6485,21 @@ static void si_init_shader_ctx(struct si_shader_context *ctx,
 static bool si_eliminate_const_output(struct si_shader_context *ctx,
 				      LLVMValueRef inst, unsigned offset)
 {
 	struct si_shader *shader = ctx->shader;
 	unsigned num_outputs = shader->selector->info.num_outputs;
 	unsigned i, default_val; /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL */
 	bool is_zero[4] = {}, is_one[4] = {};
 
 	for (i = 0; i < 4; i++) {
 		LLVMBool loses_info;
-		LLVMValueRef p = LLVMGetOperand(inst, 5 + i);
+		LLVMValueRef p = LLVMGetOperand(inst, (HAVE_LLVM >= 0x0500 ? 2 : 5) + i);
 
 		/* It's a constant expression. Undef outputs are eliminated too. */
 		if (LLVMIsUndef(p)) {
 			is_zero[i] = true;
 			is_one[i] = true;
 		} else if (LLVMIsAConstantFP(p)) {
 			double a = LLVMConstRealGetDouble(p, &loses_info);
 
 			if (a == 0)
 				is_zero[i] = true;
@@ -6569,24 +6569,26 @@ static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx)
 
 			LLVMValueRef callee = lp_get_called_value(cur);
 
 			if (!lp_is_function(callee))
 				continue;
 
 			const char *name = LLVMGetValueName(callee);
 			unsigned num_args = LLVMCountParams(callee);
 
 			/* Check if this is an export instruction. */
-			if (num_args != 9 || strcmp(name, "llvm.SI.export"))
+			if ((num_args != 9 && num_args != 8) ||
+			    (strcmp(name, "llvm.SI.export") &&
+			     strcmp(name, "llvm.amdgcn.exp.")))
 				continue;
 
-			LLVMValueRef arg = LLVMGetOperand(cur, 3);
+			LLVMValueRef arg = LLVMGetOperand(cur, HAVE_LLVM >= 0x0500 ? 0 : 3);
 			unsigned target = LLVMConstIntGetZExtValue(arg);
 
 			if (target < V_008DFC_SQ_EXP_PARAM)
 				continue;
 
 			target -= V_008DFC_SQ_EXP_PARAM;
 
 			/* Eliminate constant value PARAM exports. */
 			if (si_eliminate_const_output(ctx, cur, target)) {
 				removed_any = true;
-- 
2.7.4



More information about the mesa-dev mailing list