[llvm-branch-commits] [llvm] [AMDGPU][InstCombine] Fold zero dot operands to accumulator (PR #225003)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Sep 20 22:45:38 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Harrison Hao (harrisonGPU)
<details>
<summary>Changes</summary>
Fold AMDGPU dot intrinsics when either operand is zero.
`dot(a, 0) = 0` and `dot(0, b) = 0`, so replace the intrinsic with its accumulator.
This avoids unrelated clamp and add/sub reassociation cases.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Full diff: https://github.com/llvm/llvm-project/pull/225003.diff
2 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp (+4)
- (modified) llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll (+12-24)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index 6bfbfd189c1da..2f485b3667d87 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -1974,6 +1974,10 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
case Intrinsic::amdgcn_udot4:
case Intrinsic::amdgcn_sdot8:
case Intrinsic::amdgcn_udot8: {
+ if (match(II.getArgOperand(0), m_Zero()) ||
+ match(II.getArgOperand(1), m_Zero()))
+ return IC.replaceInstUsesWith(II, II.getArgOperand(2));
+
if (!match(II.getArgOperand(3), m_Zero()) || !II.hasOneUse())
break;
diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll b/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll
index c002c5ebecc27..017896248970c 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll
@@ -26,8 +26,7 @@ define i32 @sdot2_sub(<2 x i16> %a, <2 x i16> %b) {
define i32 @sdot2_a_zero(<2 x i16> %b) {
; CHECK-LABEL: define i32 @sdot2_a_zero(
; CHECK-SAME: <2 x i16> [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot2(<2 x i16> zeroinitializer, <2 x i16> [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -37,8 +36,7 @@ define i32 @sdot2_a_zero(<2 x i16> %b) {
define i32 @sdot2_b_zero(<2 x i16> %a) {
; CHECK-LABEL: define i32 @sdot2_b_zero(
; CHECK-SAME: <2 x i16> [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot2(<2 x i16> [[A]], <2 x i16> zeroinitializer, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot2(<2 x i16> %a, <2 x i16> zeroinitializer, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -119,8 +117,7 @@ define i32 @udot2_sub(<2 x i16> %a, <2 x i16> %b) {
define i32 @udot2_a_zero(<2 x i16> %b) {
; CHECK-LABEL: define i32 @udot2_a_zero(
; CHECK-SAME: <2 x i16> [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot2(<2 x i16> zeroinitializer, <2 x i16> [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -130,8 +127,7 @@ define i32 @udot2_a_zero(<2 x i16> %b) {
define i32 @udot2_b_zero(<2 x i16> %a) {
; CHECK-LABEL: define i32 @udot2_b_zero(
; CHECK-SAME: <2 x i16> [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot2(<2 x i16> [[A]], <2 x i16> zeroinitializer, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot2(<2 x i16> %a, <2 x i16> zeroinitializer, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -197,8 +193,7 @@ define i32 @sdot4_sub(i32 %a, i32 %b) {
define i32 @sdot4_a_zero(i32 %b) {
; CHECK-LABEL: define i32 @sdot4_a_zero(
; CHECK-SAME: i32 [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot4(i32 0, i32 [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot4(i32 0, i32 %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -208,8 +203,7 @@ define i32 @sdot4_a_zero(i32 %b) {
define i32 @sdot4_b_zero(i32 %a) {
; CHECK-LABEL: define i32 @sdot4_b_zero(
; CHECK-SAME: i32 [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot4(i32 [[A]], i32 0, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot4(i32 %a, i32 0, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -337,8 +331,7 @@ define i32 @udot4_sub(i32 %a, i32 %b) {
define i32 @udot4_a_zero(i32 %b) {
; CHECK-LABEL: define i32 @udot4_a_zero(
; CHECK-SAME: i32 [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot4(i32 0, i32 [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot4(i32 0, i32 %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -348,8 +341,7 @@ define i32 @udot4_a_zero(i32 %b) {
define i32 @udot4_b_zero(i32 %a) {
; CHECK-LABEL: define i32 @udot4_b_zero(
; CHECK-SAME: i32 [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot4(i32 [[A]], i32 0, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot4(i32 %a, i32 0, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -404,8 +396,7 @@ define i32 @sdot8_sub(i32 %a, i32 %b) {
define i32 @sdot8_a_zero(i32 %b) {
; CHECK-LABEL: define i32 @sdot8_a_zero(
; CHECK-SAME: i32 [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot8(i32 0, i32 [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot8(i32 0, i32 %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -415,8 +406,7 @@ define i32 @sdot8_a_zero(i32 %b) {
define i32 @sdot8_b_zero(i32 %a) {
; CHECK-LABEL: define i32 @sdot8_b_zero(
; CHECK-SAME: i32 [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.sdot8(i32 [[A]], i32 0, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.sdot8(i32 %a, i32 0, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -471,8 +461,7 @@ define i32 @udot8_sub(i32 %a, i32 %b) {
define i32 @udot8_a_zero(i32 %b) {
; CHECK-LABEL: define i32 @udot8_a_zero(
; CHECK-SAME: i32 [[B:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot8(i32 0, i32 [[B]], i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot8(i32 0, i32 %b, i32 7, i1 false)
%r = add i32 %dot, 9
@@ -482,8 +471,7 @@ define i32 @udot8_a_zero(i32 %b) {
define i32 @udot8_b_zero(i32 %a) {
; CHECK-LABEL: define i32 @udot8_b_zero(
; CHECK-SAME: i32 [[A:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.amdgcn.udot8(i32 [[A]], i32 0, i32 16, i1 false)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 16
;
%dot = call i32 @llvm.amdgcn.udot8(i32 %a, i32 0, i32 7, i1 false)
%r = add i32 %dot, 9
``````````
</details>
https://github.com/llvm/llvm-project/pull/225003
More information about the llvm-branch-commits
mailing list