From 44681e47955687d5590779fdc44373d3fb204fdc Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 28 Aug 2017 17:33:33 -0700 Subject: [PATCH] nir: Generalize nir_intrinsic_vote_eq The SPIR-V extension wants us to be able to do an AllEqual on any vector or scalar type. This has two implications: 1) We need to be able to handle vectors so we switch the vote_eq intrinsics to be vectorized intrinsics. 2) We need to handle floats which have different behavior with respect to +-0, NaN, etc. than the integer variant so we need two variants. Reviewed-by: Lionel Landwerlin --- src/amd/common/ac_nir_to_llvm.c | 2 +- src/compiler/glsl/glsl_to_nir.cpp | 5 +++-- src/compiler/nir/nir_intrinsics.h | 3 ++- src/compiler/nir/nir_lower_subgroups.c | 3 ++- src/compiler/nir/nir_opt_intrinsics.c | 3 ++- src/intel/compiler/brw_fs_nir.cpp | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index cca796de71b..4b3b253c439 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -4563,7 +4563,7 @@ static void visit_intrinsic(struct ac_nir_context *ctx, result = LLVMBuildSExt(ctx->ac.builder, tmp, ctx->ac.i32, ""); break; } - case nir_intrinsic_vote_eq: { + case nir_intrinsic_vote_ieq: { LLVMValueRef tmp = ac_build_vote_eq(&ctx->ac, get_src(ctx, instr->src[0])); result = LLVMBuildSExt(ctx->ac.builder, tmp, ctx->ac.i32, ""); break; diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 7a9d15015e2..80eb15f1ab1 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -814,7 +814,7 @@ nir_visitor::visit(ir_call *ir) op = nir_intrinsic_vote_all; break; case ir_intrinsic_vote_eq: - op = nir_intrinsic_vote_eq; + op = nir_intrinsic_vote_ieq; break; case ir_intrinsic_ballot: op = nir_intrinsic_ballot; @@ -1163,8 +1163,9 @@ nir_visitor::visit(ir_call *ir) } case nir_intrinsic_vote_any: case nir_intrinsic_vote_all: - case nir_intrinsic_vote_eq: { + case nir_intrinsic_vote_ieq: { nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL); + instr->num_components = 1; ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); diff --git a/src/compiler/nir/nir_intrinsics.h b/src/compiler/nir/nir_intrinsics.h index 46f67a908ed..7543d83e786 100644 --- a/src/compiler/nir/nir_intrinsics.h +++ b/src/compiler/nir/nir_intrinsics.h @@ -135,7 +135,8 @@ INTRINSIC(discard_if, 1, ARR(1), false, 0, 0, 0, xx, xx, xx, 0) /** ARB_shader_group_vote intrinsics */ INTRINSIC(vote_any, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) INTRINSIC(vote_all, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) -INTRINSIC(vote_eq, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) +INTRINSIC(vote_feq, 1, ARR(0), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) +INTRINSIC(vote_ieq, 1, ARR(0), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) /** Ballot ALU operations from SPIR-V. * diff --git a/src/compiler/nir/nir_lower_subgroups.c b/src/compiler/nir/nir_lower_subgroups.c index e45a7d723ac..3753b5e6427 100644 --- a/src/compiler/nir/nir_lower_subgroups.c +++ b/src/compiler/nir/nir_lower_subgroups.c @@ -121,7 +121,8 @@ lower_subgroups_intrin(nir_builder *b, nir_intrinsic_instr *intrin, return nir_ssa_for_src(b, intrin->src[0], 1); break; - case nir_intrinsic_vote_eq: + case nir_intrinsic_vote_feq: + case nir_intrinsic_vote_ieq: if (options->lower_vote_trivial) return nir_imm_int(b, NIR_TRUE); break; diff --git a/src/compiler/nir/nir_opt_intrinsics.c b/src/compiler/nir/nir_opt_intrinsics.c index eb394af0c10..37f08c77ef1 100644 --- a/src/compiler/nir/nir_opt_intrinsics.c +++ b/src/compiler/nir/nir_opt_intrinsics.c @@ -50,7 +50,8 @@ opt_intrinsics_impl(nir_function_impl *impl) if (nir_src_as_const_value(intrin->src[0])) replacement = nir_ssa_for_src(&b, intrin->src[0], 1); break; - case nir_intrinsic_vote_eq: + case nir_intrinsic_vote_feq: + case nir_intrinsic_vote_ieq: if (nir_src_as_const_value(intrin->src[0])) replacement = nir_imm_int(&b, NIR_TRUE); break; diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index 651997bb6ff..40d6e8bfccb 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -4423,7 +4423,7 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr bld.MOV(retype(dest, BRW_REGISTER_TYPE_D), component(res1, 0)); break; } - case nir_intrinsic_vote_eq: { + case nir_intrinsic_vote_ieq: { fs_reg value = get_nir_src(instr->src[0]); fs_reg uniformized = bld.emit_uniformize(value); const fs_builder ubld = bld.exec_all().group(1, 0); -- 2.30.2