summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConnor Abbott <[email protected]>2017-06-07 14:16:31 -0700
committerAndres Gomez <[email protected]>2017-07-08 15:47:59 +0300
commitfb5fc8d7eecef09373bdfc851f0395e7aaf2172b (patch)
tree22349e27e6f327c12d9edf13f4e1c5042d59b735
parent387e0e12a905ae3093071825240ba7f6ff7ff3b5 (diff)
ac/nir: implement 64-bit packing and unpacking
We implement the split opcodes, and tell NIR to lower the original ones. The lowering to LLVM is a little more complicated, but NIR can optimize the split ones a little better, and some NIR lowering passes that we might want to use (particularly for doubles) emit the split ones. This should fix pack/unpackDouble2x32, which seems like a bug since when we enabled the Float64 capability. It will also fix pack/unpackInt2x32 when we enable the Int64 capability. Fixes: 798ae37c ("radv: Enable Float64 support.") Signed-off-by: Connor Abbott <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> (cherry picked from commit 7168425dd77f37fa048de5a4639619763556c331)
-rw-r--r--src/amd/common/ac_nir_to_llvm.c31
-rw-r--r--src/amd/vulkan/radv_pipeline.c1
2 files changed, 32 insertions, 0 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index f513ea1efef..10081454a8e 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1774,6 +1774,37 @@ static void visit_alu(struct nir_to_llvm_context *ctx, nir_alu_instr *instr)
case nir_op_fddy_coarse:
result = emit_ddxy(ctx, instr->op, src[0]);
break;
+
+ case nir_op_unpack_64_2x32_split_x: {
+ assert(instr->src[0].src.ssa->num_components == 1);
+ LLVMValueRef tmp = LLVMBuildBitCast(ctx->builder, src[0],
+ LLVMVectorType(ctx->i32, 2),
+ "");
+ result = LLVMBuildExtractElement(ctx->builder, tmp,
+ ctx->i32zero, "");
+ break;
+ }
+
+ case nir_op_unpack_64_2x32_split_y: {
+ assert(instr->src[0].src.ssa->num_components == 1);
+ LLVMValueRef tmp = LLVMBuildBitCast(ctx->builder, src[0],
+ LLVMVectorType(ctx->i32, 2),
+ "");
+ result = LLVMBuildExtractElement(ctx->builder, tmp,
+ ctx->i32one, "");
+ break;
+ }
+
+ case nir_op_pack_64_2x32_split: {
+ LLVMValueRef tmp = LLVMGetUndef(LLVMVectorType(ctx->i32, 2));
+ tmp = LLVMBuildInsertElement(ctx->builder, tmp,
+ src[0], ctx->i32zero, "");
+ tmp = LLVMBuildInsertElement(ctx->builder, tmp,
+ src[1], ctx->i32one, "");
+ result = LLVMBuildBitCast(ctx->builder, tmp, ctx->i64, "");
+ break;
+ }
+
default:
fprintf(stderr, "Unknown NIR alu instr: ");
nir_print_instr(&instr->instr, stderr);
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index cf11362eade..e0c67ce5ea1 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -145,6 +145,7 @@ radv_optimize_nir(struct nir_shader *shader)
progress = false;
NIR_PASS_V(shader, nir_lower_vars_to_ssa);
+ NIR_PASS_V(shader, nir_lower_64bit_pack);
NIR_PASS_V(shader, nir_lower_alu_to_scalar);
NIR_PASS_V(shader, nir_lower_phis_to_scalar);