Skip to content

Conversation

@doru1004
Copy link
Contributor

Pre-commit test for PR: #162580

@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Gheorghe-Teodor Bercea (doru1004)

Changes

Pre-commit test for PR: #162580


Full diff: https://github.com/llvm/llvm-project/pull/165050.diff

1 Files Affected:

  • (added) llvm/test/CodeGen/AMDGPU/loop-vector-sink.ll (+240)
diff --git a/llvm/test/CodeGen/AMDGPU/loop-vector-sink.ll b/llvm/test/CodeGen/AMDGPU/loop-vector-sink.ll
new file mode 100644
index 0000000000000..47b0b69411edf
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/loop-vector-sink.ll
@@ -0,0 +1,240 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 < %s | FileCheck -check-prefix=OPT %s
+
+; testing insert case
+define amdgpu_kernel void @runningSum(ptr addrspace(1) %out0, ptr addrspace(1) %out1, i32 %inputElement0, i32 %inputElement1, i32 %inputIter) {
+; OPT-LABEL: define amdgpu_kernel void @runningSum(
+; OPT-SAME: ptr addrspace(1) [[OUT0:%.*]], ptr addrspace(1) [[OUT1:%.*]], i32 [[INPUTELEMENT0:%.*]], i32 [[INPUTELEMENT1:%.*]], i32 [[INPUTITER:%.*]]) #[[ATTR0:[0-9]+]] {
+; OPT-NEXT:  [[PREHEADER:.*]]:
+; OPT-NEXT:    [[VECELEMENT0:%.*]] = insertelement <2 x i32> poison, i32 [[INPUTELEMENT0]], i64 0
+; OPT-NEXT:    [[BROADCAST0:%.*]] = shufflevector <2 x i32> [[VECELEMENT0]], <2 x i32> poison, <2 x i32> zeroinitializer
+; OPT-NEXT:    [[VECELEMENT1:%.*]] = insertelement <2 x i32> poison, i32 [[INPUTELEMENT1]], i64 0
+; OPT-NEXT:    [[TMP1:%.*]] = shufflevector <2 x i32> [[VECELEMENT1]], <2 x i32> poison, <2 x i32> zeroinitializer
+; OPT-NEXT:    br label %[[LOOPBODY:.*]]
+; OPT:       [[LOOPBODY]]:
+; OPT-NEXT:    [[PREVIOUSSUM:%.*]] = phi <2 x i32> [ [[TMP1]], %[[PREHEADER]] ], [ [[RUNNINGSUM:%.*]], %[[LOOPBODY]] ]
+; OPT-NEXT:    [[ITERCOUNT:%.*]] = phi i32 [ [[INPUTITER]], %[[PREHEADER]] ], [ [[ITERSLEFT:%.*]], %[[LOOPBODY]] ]
+; OPT-NEXT:    [[RUNNINGSUM]] = add <2 x i32> [[TMP1]], [[PREVIOUSSUM]]
+; OPT-NEXT:    [[ITERSLEFT]] = sub i32 [[ITERCOUNT]], 1
+; OPT-NEXT:    [[COND:%.*]] = icmp eq i32 [[ITERSLEFT]], 0
+; OPT-NEXT:    br i1 [[COND]], label %[[LOOPEXIT:.*]], label %[[LOOPBODY]]
+; OPT:       [[LOOPEXIT]]:
+; OPT-NEXT:    [[SUMELEMENT0:%.*]] = extractelement <2 x i32> [[RUNNINGSUM]], i64 0
+; OPT-NEXT:    [[SUMELEMENT1:%.*]] = extractelement <2 x i32> [[RUNNINGSUM]], i64 1
+; OPT-NEXT:    store i32 [[SUMELEMENT0]], ptr addrspace(1) [[OUT0]], align 4
+; OPT-NEXT:    store i32 [[SUMELEMENT1]], ptr addrspace(1) [[OUT1]], align 4
+; OPT-NEXT:    ret void
+;
+preheader:
+  %vecElement0 = insertelement <2 x i32> poison, i32 %inputElement0, i64 0
+  %broadcast0 = shufflevector <2 x i32> %vecElement0, <2 x i32> poison, <2 x i32> zeroinitializer
+  %vecElement1 = insertelement <2 x i32> poison, i32 %inputElement1, i64 0
+  %broadcast1 = shufflevector <2 x i32> %vecElement1, <2 x i32> poison, <2 x i32> zeroinitializer
+  br label %loopBody
+
+loopBody:
+  %previousSum = phi <2 x i32> [ %broadcast1, %preheader ], [ %runningSum, %loopBody ]
+  %iterCount = phi i32 [ %inputIter, %preheader ], [ %itersLeft, %loopBody ]
+  %runningSum = add <2 x i32> %broadcast1, %previousSum
+  %itersLeft = sub i32 %iterCount, 1
+  %cond = icmp eq i32 %itersLeft, 0
+  br i1 %cond, label %loopExit, label %loopBody
+
+loopExit:
+  %sumElement0 = extractelement <2 x i32> %runningSum, i64 0
+  %sumElement1 = extractelement <2 x i32> %runningSum, i64 1
+  store i32 %sumElement0, ptr addrspace(1) %out0
+  store i32 %sumElement1, ptr addrspace(1) %out1
+  ret void
+}
+
+; testing extract case with single use - with divergent control flow
+; The vector has SINGLE use (extractelement), both sink into if.then
+define amdgpu_kernel void @test_sink_extract_single_use_operands(ptr addrspace(1) %out0, <2 x i32> %inputVec, i32 %tid, i32 %cond) {
+; OPT-LABEL: define amdgpu_kernel void @test_sink_extract_single_use_operands(
+; OPT-SAME: ptr addrspace(1) [[OUT0:%.*]], <2 x i32> [[INPUTVEC:%.*]], i32 [[TID:%.*]], i32 [[COND:%.*]]) #[[ATTR0]] {
+; OPT-NEXT:  [[ENTRY:.*:]]
+; OPT-NEXT:    [[RUNNINGSUM:%.*]] = add <2 x i32> [[INPUTVEC]], splat (i32 1)
+; OPT-NEXT:    [[TMP0:%.*]] = extractelement <2 x i32> [[RUNNINGSUM]], i64 0
+; OPT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TID]], [[COND]]
+; OPT-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT:       [[IF_THEN]]:
+; OPT-NEXT:    [[RESULT:%.*]] = add i32 [[TMP0]], 100
+; OPT-NEXT:    store i32 [[RESULT]], ptr addrspace(1) [[OUT0]], align 4
+; OPT-NEXT:    br label %[[IF_END]]
+; OPT:       [[IF_END]]:
+; OPT-NEXT:    ret void
+;
+entry:
+  %runningSum = add <2 x i32> %inputVec, <i32 1, i32 1>
+  %sumElement0 = extractelement <2 x i32> %runningSum, i64 0
+  %cmp = icmp slt i32 %tid, %cond
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %result = add i32 %sumElement0, 100
+  store i32 %result, ptr addrspace(1) %out0
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+; testing extract case - extracting two elements with divergent control flow
+; The vector has TWO uses (two extractelements), all sink into if.then
+define amdgpu_kernel void @test_sink_extract_operands(ptr addrspace(1) %out0, ptr addrspace(1) %out1, <4 x i32> %input_vec, i32 %tid, i32 %cond) {
+; OPT-LABEL: define amdgpu_kernel void @test_sink_extract_operands(
+; OPT-SAME: ptr addrspace(1) [[OUT0:%.*]], ptr addrspace(1) [[OUT1:%.*]], <4 x i32> [[INPUT_VEC:%.*]], i32 [[TID:%.*]], i32 [[COND:%.*]]) #[[ATTR0]] {
+; OPT-NEXT:  [[ENTRY:.*:]]
+; OPT-NEXT:    [[VEC_FULL:%.*]] = add <4 x i32> [[INPUT_VEC]], <i32 42, i32 43, i32 44, i32 45>
+; OPT-NEXT:    [[TMP0:%.*]] = extractelement <4 x i32> [[VEC_FULL]], i64 0
+; OPT-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[VEC_FULL]], i64 1
+; OPT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TID]], [[COND]]
+; OPT-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT:       [[IF_THEN]]:
+; OPT-NEXT:    [[RESULT0:%.*]] = add i32 [[TMP0]], 100
+; OPT-NEXT:    [[RESULT1:%.*]] = add i32 [[TMP1]], 200
+; OPT-NEXT:    store i32 [[RESULT0]], ptr addrspace(1) [[OUT0]], align 4
+; OPT-NEXT:    store i32 [[RESULT1]], ptr addrspace(1) [[OUT1]], align 4
+; OPT-NEXT:    br label %[[IF_END]]
+; OPT:       [[IF_END]]:
+; OPT-NEXT:    ret void
+;
+entry:
+  %vec_full = add <4 x i32> %input_vec, <i32 42, i32 43, i32 44, i32 45>
+  %extract0 = extractelement <4 x i32> %vec_full, i64 0
+  %extract1 = extractelement <4 x i32> %vec_full, i64 1
+  %cmp = icmp slt i32 %tid, %cond
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %result0 = add i32 %extract0, 100
+  %result1 = add i32 %extract1, 200
+  store i32 %result0, ptr addrspace(1) %out0
+  store i32 %result1, ptr addrspace(1) %out1
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+; testing shuffle case with divergent control flow - shuffles sink into if.then
+define amdgpu_kernel void @test_shuffle_insert_subvector(ptr addrspace(1) %ptr, <4 x i16> %vec1, <4 x i16> %vec2, i32 %tid, i32 %cond) {
+; OPT-LABEL: define amdgpu_kernel void @test_shuffle_insert_subvector(
+; OPT-SAME: ptr addrspace(1) [[PTR:%.*]], <4 x i16> [[VEC1:%.*]], <4 x i16> [[VEC2:%.*]], i32 [[TID:%.*]], i32 [[COND:%.*]]) #[[ATTR0]] {
+; OPT-NEXT:  [[ENTRY:.*:]]
+; OPT-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[VEC1]], <4 x i16> [[VEC2]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; OPT-NEXT:    [[SHUFFLE2:%.*]] = shufflevector <4 x i16> [[VEC1]], <4 x i16> [[VEC2]], <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+; OPT-NEXT:    [[SHUFFLE3:%.*]] = shufflevector <4 x i16> [[VEC1]], <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+; OPT-NEXT:    [[SHUFFLE4:%.*]] = shufflevector <4 x i16> [[VEC2]], <4 x i16> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+; OPT-NEXT:    [[SHUFFLE5:%.*]] = shufflevector <4 x i16> [[SHUFFLE]], <4 x i16> [[SHUFFLE2]], <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+; OPT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TID]], [[COND]]
+; OPT-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT:       [[IF_THEN]]:
+; OPT-NEXT:    [[RESULT_VEC:%.*]] = add <4 x i16> [[SHUFFLE5]], <i16 100, i16 200, i16 300, i16 400>
+; OPT-NEXT:    [[OTHER_RESULT:%.*]] = mul <4 x i16> [[SHUFFLE3]], splat (i16 2)
+; OPT-NEXT:    [[MORE_RESULT:%.*]] = sub <4 x i16> [[SHUFFLE4]], splat (i16 5)
+; OPT-NEXT:    store <4 x i16> [[RESULT_VEC]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    store <4 x i16> [[OTHER_RESULT]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    store <4 x i16> [[MORE_RESULT]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    br label %[[IF_END]]
+; OPT:       [[IF_END]]:
+; OPT-NEXT:    ret void
+;
+entry:
+  %shuffle = shufflevector <4 x i16> %vec1, <4 x i16> %vec2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+  %shuffle2 = shufflevector <4 x i16> %vec1, <4 x i16> %vec2, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+  %shuffle3 = shufflevector <4 x i16> %vec1, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+  %shuffle4 = shufflevector <4 x i16> %vec2, <4 x i16> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+  %shuffle5 = shufflevector <4 x i16> %shuffle, <4 x i16> %shuffle2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+  %cmp = icmp slt i32 %tid, %cond
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %result_vec = add <4 x i16> %shuffle5, <i16 100, i16 200, i16 300, i16 400>
+  %other_result = mul <4 x i16> %shuffle3, <i16 2, i16 2, i16 2, i16 2>
+  %more_result = sub <4 x i16> %shuffle4, <i16 5, i16 5, i16 5, i16 5>
+  store <4 x i16> %result_vec, ptr addrspace(1) %ptr
+  store <4 x i16> %other_result, ptr addrspace(1) %ptr
+  store <4 x i16> %more_result, ptr addrspace(1) %ptr
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+; testing shuffle extract subvector with divergent control flow - shuffles sink into if.then
+define amdgpu_kernel void @test_shuffle_extract_subvector(ptr addrspace(1) %ptr, <4 x i16> %input_vec, i32 %tid, i32 %cond) {
+; OPT-LABEL: define amdgpu_kernel void @test_shuffle_extract_subvector(
+; OPT-SAME: ptr addrspace(1) [[PTR:%.*]], <4 x i16> [[INPUT_VEC:%.*]], i32 [[TID:%.*]], i32 [[COND:%.*]]) #[[ATTR0]] {
+; OPT-NEXT:  [[ENTRY:.*:]]
+; OPT-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[INPUT_VEC]], <4 x i16> poison, <2 x i32> <i32 2, i32 3>
+; OPT-NEXT:    [[SHUFFLE2:%.*]] = shufflevector <4 x i16> [[INPUT_VEC]], <4 x i16> poison, <2 x i32> <i32 0, i32 1>
+; OPT-NEXT:    [[SHUFFLE3:%.*]] = shufflevector <4 x i16> [[INPUT_VEC]], <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+; OPT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TID]], [[COND]]
+; OPT-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT:       [[IF_THEN]]:
+; OPT-NEXT:    [[RESULT_VEC:%.*]] = add <2 x i16> [[SHUFFLE]], <i16 100, i16 200>
+; OPT-NEXT:    [[RESULT_VEC2:%.*]] = mul <2 x i16> [[SHUFFLE2]], splat (i16 3)
+; OPT-NEXT:    [[RESULT_VEC3:%.*]] = sub <4 x i16> [[SHUFFLE3]], splat (i16 10)
+; OPT-NEXT:    store <2 x i16> [[RESULT_VEC]], ptr addrspace(1) [[PTR]], align 4
+; OPT-NEXT:    store <2 x i16> [[RESULT_VEC2]], ptr addrspace(1) [[PTR]], align 4
+; OPT-NEXT:    store <4 x i16> [[RESULT_VEC3]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    br label %[[IF_END]]
+; OPT:       [[IF_END]]:
+; OPT-NEXT:    ret void
+;
+entry:
+  %shuffle = shufflevector <4 x i16> %input_vec, <4 x i16> poison, <2 x i32> <i32 2, i32 3>
+  %shuffle2 = shufflevector <4 x i16> %input_vec, <4 x i16> poison, <2 x i32> <i32 0, i32 1>
+  %shuffle3 = shufflevector <4 x i16> %input_vec, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+  %cmp = icmp slt i32 %tid, %cond
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %result_vec = add <2 x i16> %shuffle, <i16 100, i16 200>
+  %result_vec2 = mul <2 x i16> %shuffle2, <i16 3, i16 3>
+  %result_vec3 = sub <4 x i16> %shuffle3, <i16 10, i16 10, i16 10, i16 10>
+  store <2 x i16> %result_vec, ptr addrspace(1) %ptr
+  store <2 x i16> %result_vec2, ptr addrspace(1) %ptr
+  store <4 x i16> %result_vec3, ptr addrspace(1) %ptr
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+; testing shuffle sink with widening operations and divergent control flow
+define amdgpu_kernel void @test_shuffle_sink_operands(ptr addrspace(1) %ptr, <2 x i16> %input_vec, <2 x i16> %input_vec2, i32 %tid, i32 %cond) {
+; OPT-LABEL: define amdgpu_kernel void @test_shuffle_sink_operands(
+; OPT-SAME: ptr addrspace(1) [[PTR:%.*]], <2 x i16> [[INPUT_VEC:%.*]], <2 x i16> [[INPUT_VEC2:%.*]], i32 [[TID:%.*]], i32 [[COND:%.*]]) #[[ATTR0]] {
+; OPT-NEXT:  [[ENTRY:.*:]]
+; OPT-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x i16> [[INPUT_VEC]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; OPT-NEXT:    [[SHUFFLE2:%.*]] = shufflevector <2 x i16> [[INPUT_VEC2]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; OPT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TID]], [[COND]]
+; OPT-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT:       [[IF_THEN]]:
+; OPT-NEXT:    [[RESULT_VEC:%.*]] = add <4 x i16> [[SHUFFLE]], <i16 100, i16 200, i16 300, i16 400>
+; OPT-NEXT:    [[RESULT_VEC2:%.*]] = mul <4 x i16> [[SHUFFLE2]], splat (i16 5)
+; OPT-NEXT:    store <4 x i16> [[RESULT_VEC]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    store <4 x i16> [[RESULT_VEC2]], ptr addrspace(1) [[PTR]], align 8
+; OPT-NEXT:    br label %[[IF_END]]
+; OPT:       [[IF_END]]:
+; OPT-NEXT:    ret void
+;
+entry:
+  %shuffle = shufflevector <2 x i16> %input_vec, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+  %shuffle2 = shufflevector <2 x i16> %input_vec2, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+  %cmp = icmp slt i32 %tid, %cond
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %result_vec = add <4 x i16> %shuffle, <i16 100, i16 200, i16 300, i16 400>
+  %result_vec2 = mul <4 x i16> %shuffle2, <i16 5, i16 5, i16 5, i16 5>
+  store <4 x i16> %result_vec, ptr addrspace(1) %ptr
+  store <4 x i16> %result_vec2, ptr addrspace(1) %ptr
+  br label %if.end
+
+if.end:
+  ret void
+}

@doru1004 doru1004 requested a review from jrbyrnes October 24, 2025 22:44
@doru1004 doru1004 force-pushed the precommited-tests-for-sinking branch from a59f0b8 to b8d5815 Compare October 27, 2025 14:15
@doru1004 doru1004 force-pushed the precommited-tests-for-sinking branch from b8d5815 to 7e349f4 Compare October 27, 2025 15:49
@doru1004 doru1004 merged commit bce7f7c into llvm:main Oct 27, 2025
10 checks passed
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants