diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index 40d5ff49f05..2adfec1ad75 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -308,7 +308,14 @@ LLVMValueRef ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name, } call = LLVMBuildCall2(ctx->builder, function_type, function, params, param_count, ""); - ac_add_func_attributes(ctx->context, call, attrib_mask); + + if (attrib_mask & AC_FUNC_ATTR_READNONE) + LLVMAddCallSiteAttribute(call, -1, ac_get_llvm_attribute(ctx->context, "readnone")); + + if (attrib_mask & AC_FUNC_ATTR_CONVERGENT) + LLVMAddCallSiteAttribute(call, -1, ac_get_llvm_attribute(ctx->context, "convergent")); + + LLVMAddCallSiteAttribute(call, -1, ac_get_llvm_attribute(ctx->context, "nounwind")); return call; } @@ -505,7 +512,7 @@ LLVMValueRef ac_build_ballot(struct ac_llvm_context *ctx, LLVMValueRef value) return ac_build_intrinsic( ctx, name, ctx->iN_wavemask, args, 3, - AC_FUNC_ATTR_NOUNWIND | AC_FUNC_ATTR_READNONE | AC_FUNC_ATTR_CONVERGENT); + AC_FUNC_ATTR_READNONE | AC_FUNC_ATTR_CONVERGENT); } LLVMValueRef ac_get_i1_sgpr_mask(struct ac_llvm_context *ctx, LLVMValueRef value) @@ -525,7 +532,7 @@ LLVMValueRef ac_get_i1_sgpr_mask(struct ac_llvm_context *ctx, LLVMValueRef value return ac_build_intrinsic( ctx, name, ctx->iN_wavemask, args, 3, - AC_FUNC_ATTR_NOUNWIND | AC_FUNC_ATTR_READNONE | AC_FUNC_ATTR_CONVERGENT); + AC_FUNC_ATTR_READNONE | AC_FUNC_ATTR_CONVERGENT); } LLVMValueRef ac_build_vote_all(struct ac_llvm_context *ctx, LLVMValueRef value) diff --git a/src/amd/llvm/ac_llvm_util.c b/src/amd/llvm/ac_llvm_util.c index f98ef4f32d1..558d726ec82 100644 --- a/src/amd/llvm/ac_llvm_util.c +++ b/src/amd/llvm/ac_llvm_util.c @@ -257,39 +257,22 @@ static const char *attr_to_str(enum ac_func_attr attr) return "inreg"; case AC_FUNC_ATTR_NOALIAS: return "noalias"; - case AC_FUNC_ATTR_NOUNWIND: - return "nounwind"; - case AC_FUNC_ATTR_READNONE: - return "readnone"; - case AC_FUNC_ATTR_CONVERGENT: - return "convergent"; default: fprintf(stderr, "Unhandled function attribute: %x\n", attr); return 0; } } +LLVMAttributeRef ac_get_llvm_attribute(LLVMContextRef ctx, const char *str) +{ + return LLVMCreateEnumAttribute(ctx, LLVMGetEnumAttributeKindForName(str, strlen(str)), 0); +} + void ac_add_function_attr(LLVMContextRef ctx, LLVMValueRef function, int attr_idx, enum ac_func_attr attr) { - const char *attr_name = attr_to_str(attr); - unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); - LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(ctx, kind_id, 0); - - if (LLVMIsAFunction(function)) - LLVMAddAttributeAtIndex(function, attr_idx, llvm_attr); - else - LLVMAddCallSiteAttribute(function, attr_idx, llvm_attr); -} - -void ac_add_func_attributes(LLVMContextRef ctx, LLVMValueRef function, unsigned attrib_mask) -{ - attrib_mask |= AC_FUNC_ATTR_NOUNWIND; - - while (attrib_mask) { - enum ac_func_attr attr = 1u << u_bit_scan(&attrib_mask); - ac_add_function_attr(ctx, function, -1, attr); - } + assert(LLVMIsAFunction(function)); + LLVMAddAttributeAtIndex(function, attr_idx, ac_get_llvm_attribute(ctx, attr_to_str(attr))); } void ac_dump_module(LLVMModuleRef module) diff --git a/src/amd/llvm/ac_llvm_util.h b/src/amd/llvm/ac_llvm_util.h index 919dead860a..a3f1ced4790 100644 --- a/src/amd/llvm/ac_llvm_util.h +++ b/src/amd/llvm/ac_llvm_util.h @@ -42,12 +42,14 @@ struct ac_llvm_context; enum ac_func_attr { + /* Function and parameter attributes. */ AC_FUNC_ATTR_ALWAYSINLINE = (1 << 0), - AC_FUNC_ATTR_INREG = (1 << 2), - AC_FUNC_ATTR_NOALIAS = (1 << 3), - AC_FUNC_ATTR_NOUNWIND = (1 << 4), - AC_FUNC_ATTR_READNONE = (1 << 5), - AC_FUNC_ATTR_CONVERGENT = (1 << 8), + AC_FUNC_ATTR_INREG = (1 << 1), + AC_FUNC_ATTR_NOALIAS = (1 << 2), + + /* Call attributes. */ + AC_FUNC_ATTR_READNONE = (1 << 3), + AC_FUNC_ATTR_CONVERGENT = (1 << 4), }; enum ac_target_machine_options @@ -87,9 +89,9 @@ void ac_reset_llvm_all_options_occurences(); void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes); void ac_add_attr_alignment(LLVMValueRef val, uint64_t bytes); bool ac_is_sgpr_param(LLVMValueRef param); +LLVMAttributeRef ac_get_llvm_attribute(LLVMContextRef ctx, const char *str); void ac_add_function_attr(LLVMContextRef ctx, LLVMValueRef function, int attr_idx, enum ac_func_attr attr); -void ac_add_func_attributes(LLVMContextRef ctx, LLVMValueRef function, unsigned attrib_mask); void ac_dump_module(LLVMModuleRef module); LLVMModuleRef ac_create_module(LLVMTargetMachineRef tm, LLVMContextRef ctx); LLVMBuilderRef ac_create_builder(LLVMContextRef ctx, enum ac_float_mode float_mode); diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index 4ca98bca5ee..015cc1ff9d4 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -3081,7 +3081,7 @@ static LLVMValueRef visit_first_invocation(struct ac_nir_context *ctx) /* The second argument is whether cttz(0) should be defined, but we do not care. */ LLVMValueRef args[] = {active_set, ctx->ac.i1false}; LLVMValueRef result = ac_build_intrinsic(&ctx->ac, intr, ctx->ac.iN_wavemask, args, 2, - AC_FUNC_ATTR_NOUNWIND | AC_FUNC_ATTR_READNONE); + AC_FUNC_ATTR_READNONE); return LLVMBuildTrunc(ctx->ac.builder, result, ctx->ac.i32, ""); }