[llvm-branch-commits] [llvm] [AMDGPU][InstCombine] Canonicalize dot constant operands (PR #225083)

Harrison Hao via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Sep 21 07:11:00 PDT 2026


https://github.com/harrisonGPU updated https://github.com/llvm/llvm-project/pull/225083

>From cd5b83426adf91e423554ceabb1204b6e5be9da3 Mon Sep 17 00:00:00 2001
From: Harrison Hao <tsworld1314 at gmail.com>
Date: Mon, 21 Sep 2026 21:01:31 +0800
Subject: [PATCH] [AMDGPU][InstCombine] Canonicalize dot constant operands

Move constant dot product source operands to the right hand side
and add tests for signed and unsigned dot intrinsics.
---
 .../AMDGPU/AMDGPUInstCombineIntrinsic.cpp     |  9 +++++++
 .../InstCombine/AMDGPU/llvm.amdgcn.dot.ll     | 24 +++++++++----------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index dcbdde6ccbdfa3..f6c08bdc58d3d9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -1974,6 +1974,15 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
   case Intrinsic::amdgcn_udot4:
   case Intrinsic::amdgcn_sdot8:
   case Intrinsic::amdgcn_udot8: {
+    Value *Src0 = II.getArgOperand(0);
+    Value *Src1 = II.getArgOperand(1);
+
+    if (isa<Constant>(Src0) && !isa<Constant>(Src1)) {
+      II.setArgOperand(0, Src1);
+      II.setArgOperand(1, Src0);
+      return &II;
+    }
+
     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 df73418a09fae0..72e7340c459a62 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/llvm.amdgcn.dot.ll
@@ -26,7 +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:    [[R:%.*]] = call i32 @llvm.amdgcn.sdot2(<2 x i16> [[B]], <2 x i16> zeroinitializer, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 7, i1 false)
@@ -37,7 +37,7 @@ define i32 @sdot2_a_zero(<2 x i16> %b) {
 define i32 @sdot2_const_lhs(<2 x i16> %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @sdot2_const_lhs(
 ; CHECK-SAME: <2 x i16> [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot2(<2 x i16> zeroinitializer, <2 x i16> [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot2(<2 x i16> [[B]], <2 x i16> zeroinitializer, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 %acc, i1 false)
@@ -129,7 +129,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:    [[R:%.*]] = call i32 @llvm.amdgcn.udot2(<2 x i16> [[B]], <2 x i16> zeroinitializer, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.udot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 7, i1 false)
@@ -140,7 +140,7 @@ define i32 @udot2_a_zero(<2 x i16> %b) {
 define i32 @udot2_const_lhs(<2 x i16> %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @udot2_const_lhs(
 ; CHECK-SAME: <2 x i16> [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot2(<2 x i16> zeroinitializer, <2 x i16> [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot2(<2 x i16> [[B]], <2 x i16> zeroinitializer, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.udot2(<2 x i16> zeroinitializer, <2 x i16> %b, i32 %acc, i1 false)
@@ -217,7 +217,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:    [[R:%.*]] = call i32 @llvm.amdgcn.sdot4(i32 [[B]], i32 0, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot4(i32 0, i32 %b, i32 7, i1 false)
@@ -228,7 +228,7 @@ define i32 @sdot4_a_zero(i32 %b) {
 define i32 @sdot4_const_lhs(i32 %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @sdot4_const_lhs(
 ; CHECK-SAME: i32 [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot4(i32 16843009, i32 [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot4(i32 [[B]], i32 16843009, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot4(i32 16843009, i32 %b, i32 %acc, i1 false)
@@ -376,7 +376,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:    [[R:%.*]] = call i32 @llvm.amdgcn.udot4(i32 [[B]], i32 0, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.udot4(i32 0, i32 %b, i32 7, i1 false)
@@ -387,7 +387,7 @@ define i32 @udot4_a_zero(i32 %b) {
 define i32 @udot4_const_lhs(i32 %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @udot4_const_lhs(
 ; CHECK-SAME: i32 [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot4(i32 6, i32 [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot4(i32 [[B]], i32 6, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.udot4(i32 6, i32 %b, i32 %acc, i1 false)
@@ -453,7 +453,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:    [[R:%.*]] = call i32 @llvm.amdgcn.sdot8(i32 [[B]], i32 0, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot8(i32 0, i32 %b, i32 7, i1 false)
@@ -464,7 +464,7 @@ define i32 @sdot8_a_zero(i32 %b) {
 define i32 @sdot8_const_lhs(i32 %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @sdot8_const_lhs(
 ; CHECK-SAME: i32 [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot8(i32 16843009, i32 [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.sdot8(i32 [[B]], i32 16843009, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.sdot8(i32 16843009, i32 %b, i32 %acc, i1 false)
@@ -530,7 +530,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:    [[R:%.*]] = call i32 @llvm.amdgcn.udot8(i32 [[B]], i32 0, i32 16, i1 false)
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %dot = call i32 @llvm.amdgcn.udot8(i32 0, i32 %b, i32 7, i1 false)
@@ -541,7 +541,7 @@ define i32 @udot8_a_zero(i32 %b) {
 define i32 @udot8_const_lhs(i32 %b, i32 %acc) {
 ; CHECK-LABEL: define i32 @udot8_const_lhs(
 ; CHECK-SAME: i32 [[B:%.*]], i32 [[ACC:%.*]]) {
-; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot8(i32 0, i32 [[B]], i32 [[ACC]], i1 false)
+; CHECK-NEXT:    [[DOT:%.*]] = call i32 @llvm.amdgcn.udot8(i32 [[B]], i32 0, i32 [[ACC]], i1 false)
 ; CHECK-NEXT:    ret i32 [[DOT]]
 ;
   %dot = call i32 @llvm.amdgcn.udot8(i32 0, i32 %b, i32 %acc, i1 false)



More information about the llvm-branch-commits mailing list