summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schürmann <daniel.schuermann@campus.tu-berlin.de>2018-03-06 15:04:29 +0100
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2018-04-14 01:03:15 +0200
commit4b0616e533170e1384111259ef500ed8c67912fa (patch)
treed5414e88d66d47c36ee38652183b4678c1fa13a4
parentd5f7ebda3ec03c35ee3b496f96fb3269b1d4b946 (diff)
ac: handle subgroup intrinsics
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
-rw-r--r--src/amd/common/ac_nir_to_llvm.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 7c2bd5c0cca..3a3aa72988e 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -2805,36 +2805,12 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
result = ac_build_ballot(&ctx->ac, get_src(ctx, instr->src[0]));
break;
case nir_intrinsic_read_invocation:
- case nir_intrinsic_read_first_invocation: {
- LLVMValueRef args[2];
-
- /* Value */
- args[0] = get_src(ctx, instr->src[0]);
-
- unsigned num_args;
- const char *intr_name;
- if (instr->intrinsic == nir_intrinsic_read_invocation) {
- num_args = 2;
- intr_name = "llvm.amdgcn.readlane";
-
- /* Invocation */
- args[1] = get_src(ctx, instr->src[1]);
- } else {
- num_args = 1;
- intr_name = "llvm.amdgcn.readfirstlane";
- }
-
- /* We currently have no other way to prevent LLVM from lifting the icmp
- * calls to a dominating basic block.
- */
- ac_build_optimization_barrier(&ctx->ac, &args[0]);
-
- result = ac_build_intrinsic(&ctx->ac, intr_name,
- ctx->ac.i32, args, num_args,
- AC_FUNC_ATTR_READNONE |
- AC_FUNC_ATTR_CONVERGENT);
+ result = ac_build_readlane(&ctx->ac, get_src(ctx, instr->src[0]),
+ get_src(ctx, instr->src[1]));
+ break;
+ case nir_intrinsic_read_first_invocation:
+ result = ac_build_readlane(&ctx->ac, get_src(ctx, instr->src[0]), NULL);
break;
- }
case nir_intrinsic_load_subgroup_invocation:
result = ac_get_thread_id(&ctx->ac);
break;
@@ -3088,6 +3064,41 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
result = LLVMBuildSExt(ctx->ac.builder, tmp, ctx->ac.i32, "");
break;
}
+ case nir_intrinsic_shuffle:
+ result = ac_build_shuffle(&ctx->ac, get_src(ctx, instr->src[0]),
+ get_src(ctx, instr->src[1]));
+ break;
+ case nir_intrinsic_reduce:
+ result = ac_build_reduce(&ctx->ac,
+ get_src(ctx, instr->src[0]),
+ instr->const_index[0],
+ instr->const_index[1]);
+ break;
+ case nir_intrinsic_inclusive_scan:
+ result = ac_build_inclusive_scan(&ctx->ac,
+ get_src(ctx, instr->src[0]),
+ instr->const_index[0]);
+ break;
+ case nir_intrinsic_exclusive_scan:
+ result = ac_build_exclusive_scan(&ctx->ac,
+ get_src(ctx, instr->src[0]),
+ instr->const_index[0]);
+ break;
+ case nir_intrinsic_quad_broadcast: {
+ unsigned lane = nir_src_as_const_value(instr->src[1])->u32[0];
+ result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]),
+ lane, lane, lane, lane);
+ break;
+ }
+ case nir_intrinsic_quad_swap_horizontal:
+ result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]), 1, 0, 3 ,2);
+ break;
+ case nir_intrinsic_quad_swap_vertical:
+ result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]), 2, 3, 0 ,1);
+ break;
+ case nir_intrinsic_quad_swap_diagonal:
+ result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]), 3, 2, 1 ,0);
+ break;
default:
fprintf(stderr, "Unknown intrinsic: ");
nir_print_instr(&instr->instr, stderr);