[llvm] [AMDGPU] Preserve call-site attributes rebuilding an intrinsic (PR #201549)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 04:18:42 PDT 2026
https://github.com/gretay-amd created https://github.com/llvm/llvm-project/pull/201549
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)).
>From ea118ac2fcc3cdc7feb47ee7e0ff17b129a1624e Mon Sep 17 00:00:00 2001
From: Greta Yorsh <Greta.Yorsh at amd.com>
Date: Thu, 4 Jun 2026 12:06:48 +0100
Subject: [PATCH 1/2] [AMDGPU] Add test for call-site attribute preservation in
InstCombine
Pre-commit: the CHECK lines capture current (buggy) behavior where
InstCombine's AMDGPU intrinsic rewrites drop call-site-only attributes
(here, memory(argmem: read) via #1) when rebuilding the call with
IC.Builder.CreateIntrinsic. A follow-up commit fixes the rewrites and
updates the expected output.
Assisted-by: Claude <noreply at anthropic.com>
---
.../AMDGPU/preserve-callsite-attrs.ll | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll
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..d2c2d1f0f9b81
--- /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)
+; 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) }
>From 539982ea67b8eee0b5fee0c6986199eb60ee033a Mon Sep 17 00:00:00 2001
From: Greta Yorsh <Greta.Yorsh at amd.com>
Date: Thu, 4 Jun 2026 12:07:11 +0100
Subject: [PATCH 2/2] [AMDGPU] Preserve call-site attributes when InstCombine
rebuilds an intrinsic
AMDGPUCodeGenPrepare uses IC.Builder.CreateIntrinsic to rebuild intrinsics
calls. CreateIntrinsic only inherits attributes from the intrinsic
declaration, so any call-site only attributes are silently dropped.
Copy the original AttributeList onto the new call in both helpers so
call-site attributes survive the rebuild.
The change is needed in both modifyIntrinsicCall simplifications) and
simplifyAMDGCNMemoryIntrinsicDemanded (used for example by the
demanded-elements dmask shrink).
The test update shows the added #[[ATTR1]] on the rebuilt call.
Assisted-by: Claude <noreply at anthropic.com>
---
llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp | 5 +++++
.../Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
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
index d2c2d1f0f9b81..1e49c668a7c5b 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/preserve-callsite-attrs.ll
@@ -13,7 +13,7 @@
; 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)
+; 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
More information about the llvm-commits
mailing list