[llvm] [AMDGPU] Preserve call-site attributes rebuilding an intrinsic (PR #201549)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 04:19:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: gretay-amd
<details>
<summary>Changes</summary>
This PR copies the original call-site attributes onto the new call.
`AMDGPUCodeGenPrepare` uses `IC.Builder.CreateIntrinsic` to rebuild intrinsic calls. `CreateIntrinsic` only inherits attributes from the intrinsic declaration, and any call-site only attributes are silently dropped.
The change is needed in both `modifyIntrinsicCall simplifications` and `simplifyAMDGCNMemoryIntrinsicDemanded`. The new test exercises both transformations firing in sequence on the same `image.sample` call. Two commits: the first adds the test that drops the attribute and then the second commit fixes the bug and the test.
This fix was originally introduced by @<!-- -->dstutt in the context of waterfall intrinsics #<!-- -->192409, but the issue and the fix are independent (see review comment [r3348760419](https://github.com/llvm/llvm-project/pull/192409#discussion_r3348760419)).
---
Full diff: https://github.com/llvm/llvm-project/pull/201549.diff
2 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp (+5)
- (added) llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll (+29)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index 2370c379e75f5..4b5eb0ee6abd3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -143,6 +143,9 @@ static std::optional<Instruction *> modifyIntrinsicCall(
NewCall->copyMetadata(OldIntr);
if (isa<FPMathOperator>(NewCall))
NewCall->copyFastMathFlags(&OldIntr);
+ // Copy attributes
+ AttributeList OldAttrList = OldIntr.getAttributes();
+ NewCall->setAttributes(OldAttrList);
// Erase and replace uses
if (!InstToReplace.getType()->isVoidTy())
@@ -2379,6 +2382,8 @@ static Value *simplifyAMDGCNMemoryIntrinsicDemanded(InstCombiner &IC,
IC.Builder.CreateIntrinsic(II.getIntrinsicID(), OverloadTys, Args);
NewCall->takeName(&II);
NewCall->copyMetadata(II);
+ AttributeList OldAttrList = II.getAttributes();
+ NewCall->setAttributes(OldAttrList);
if (IsLoad) {
if (NewNumElts == 1) {
diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll b/llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll
new file mode 100644
index 0000000000000..1e49c668a7c5b
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine -mtriple=amdgcn-amd-amdhsa %s | FileCheck %s
+
+; InstCombine runs two transforms on the same image.sample call:
+; 1. modifyIntrinsicCall: lod = 0.0 rewrites image.sample.l.1d to
+; image.sample.lz.1d, dropping the lod operand.
+; 2. simplifyAMDGCNMemoryIntrinsicDemanded: only lanes 0 and 1 are used,
+; so the dmask shrinks from 15 to 3 and the return type shrinks from
+; <4 x float> to <2 x float>.
+; Each transform rebuilds the call with IC.Builder.CreateIntrinsic, which
+; would drop any call-site-only attributes (here, memory(argmem: read)
+; attached via #1). The new call is guaranteed to inherit attributes from
+; the intrinsic declaration, but not call-site attributes.
+define amdgpu_ps <2 x float> @image_l_to_lz_shrink(<8 x i32> inreg %rsrc, float %s, <4 x i32> inreg %samp) {
+; CHECK-LABEL: @image_l_to_lz_shrink(
+; CHECK-NEXT: [[V4:%.*]] = call <2 x float> @llvm.amdgcn.image.sample.lz.1d.v2f32.f32.v8i32.v4i32(i32 3, float [[S:%.*]], <8 x i32> [[RSRC:%.*]], <4 x i32> [[SAMP:%.*]], i1 false, i32 0, i32 0) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: ret <2 x float> [[V4]]
+;
+ %v4 = call <4 x float> @llvm.amdgcn.image.sample.l.1d.v4f32.f32.v8i32.v4i32(i32 15, float %s, float 0.0, <8 x i32> %rsrc, <4 x i32> %samp, i1 false, i32 0, i32 0) #1
+ %e0 = extractelement <4 x float> %v4, i32 0
+ %e1 = extractelement <4 x float> %v4, i32 1
+ %r0 = insertelement <2 x float> poison, float %e0, i32 0
+ %r1 = insertelement <2 x float> %r0, float %e1, i32 1
+ ret <2 x float> %r1
+}
+
+declare <4 x float> @llvm.amdgcn.image.sample.l.1d.v4f32.f32.v8i32.v4i32(i32, float, float, <8 x i32>, <4 x i32>, i1, i32, i32)
+
+attributes #1 = { memory(argmem: read) }
``````````
</details>
https://github.com/llvm/llvm-project/pull/201549
More information about the llvm-commits
mailing list