From aff4a630aad2b7a4edc70b2e2c8f29748fc06c76 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(+) --- 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); +} --- a/src/amd/common/ac_llvm_util.h +++ b/src/amd/common/ac_llvm_util.h @@ -37,6 +37,7 @@ LLVMTargetMachineRef ac_create_target_ma 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); #ifdef __cplusplus } --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -4684,6 +4684,7 @@ static void build_tex_intrinsic(const st 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 = ""; @@ -4705,6 +4706,7 @@ static void build_tex_intrinsic(const st "llvm.SI.image.load.mip"; is_shadow = false; has_offset = false; + has_sampler = false; break; case TGSI_OPCODE_LODQ: name = "llvm.SI.getlod"; @@ -4763,6 +4765,7 @@ static void build_tex_intrinsic(const st */ 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; } } @@ -4771,6 +4774,7 @@ static void build_tex_intrinsic(const st 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(