From cb525770f98b81659119ab33d3b902b63473bde3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Fri, 4 Nov 2016 16:11:31 +0100 Subject: [PATCH] radeonsi: apply the Convergent attribute to old-style image intrinsics TODO this is pending LLVM support This fixes piglit glsl-1.10/execution/fs-texture-select and similar bugs. At some point, we should use new-style intrinsics where the Convergent attribute from the .td files in LLVM is honored. However, those aren't ReadNone, and that might hurt the quality of generated code. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97988 --- src/amd/common/ac_llvm_helper.cpp | 16 ++++++++++++++++ src/amd/common/ac_llvm_util.h | 1 + src/gallium/drivers/radeonsi/si_shader.c | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/src/amd/common/ac_llvm_helper.cpp b/src/amd/common/ac_llvm_helper.cpp index 594339e..bae184f 100644 --- a/src/amd/common/ac_llvm_helper.cpp +++ b/src/amd/common/ac_llvm_helper.cpp @@ -53,3 +53,19 @@ bool ac_is_sgpr_param(LLVMValueRef arg) return AS.hasAttribute(ArgNo + 1, llvm::Attribute::ByVal) || AS.hasAttribute(ArgNo + 1, llvm::Attribute::InReg); } + +/** + * Fix the definition of an old-style llvm.SI.image intrinsic. + */ +void ac_fixup_image_intrinsic(LLVMModuleRef module, const char *intr_name, + bool has_sampler) +{ + if (HAVE_LLVM < 0x0400) + return; + + LLVMValueRef func = LLVMGetNamedFunction(module, intr_name); + llvm::Function *F = llvm::unwrap(func); + F->addAttribute(1 + 2, llvm::Attribute::Convergent); + if (has_sampler) + F->addAttribute(1 + 3, llvm::Attribute::Convergent); +} diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h index 1f37a12..1c51756 100644 --- a/src/amd/common/ac_llvm_util.h +++ b/src/amd/common/ac_llvm_util.h @@ -48,6 +48,7 @@ LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family, bool su void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes); bool ac_is_sgpr_param(LLVMValueRef param); +void ac_fixup_image_intrinsic(LLVMModuleRef, const char *intr_name, bool has_sampler); void ac_add_function_attr(LLVMValueRef function, diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 89229ee..3b6f67d 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -4604,6 +4604,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action, char intr_name[127]; bool has_offset = inst->Texture.NumOffsets > 0; bool is_shadow = tgsi_is_shadow_target(target); + bool has_sampler = true; char type[64]; const char *name = "llvm.SI.image.sample"; const char *infix = ""; @@ -4625,6 +4626,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action, "llvm.SI.image.load.mip"; is_shadow = false; has_offset = false; + has_sampler = false; break; case TGSI_OPCODE_LODQ: name = "llvm.SI.getlod"; @@ -4683,6 +4685,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action, */ si_lower_gather4_integer(ctx, emit_data, intr_name, (int)has_offset + (int)is_shadow); + ac_fixup_image_intrinsic(ctx->gallivm.module, intr_name, has_sampler); return; } } @@ -4691,6 +4694,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action, base->gallivm->builder, intr_name, emit_data->dst_type, emit_data->args, emit_data->arg_count, LP_FUNC_ATTR_READNONE); + ac_fixup_image_intrinsic(ctx->gallivm.module, intr_name, has_sampler); } static void si_llvm_emit_txqs( -- 2.9.3