[llvm] [AMDGPU] Fold constants in v2bf16 canonicalization (PR #214384)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 7 18:11:24 PDT 2026


https://github.com/LU-JOHN updated https://github.com/llvm/llvm-project/pull/214384

>From 7405d932b784ba2b1b6a7cc11a8398e6a5799441 Mon Sep 17 00:00:00 2001
From: John Lu <John.Lu at amd.com>
Date: Wed, 5 Aug 2026 20:37:10 -0500
Subject: [PATCH 1/3] Fold constants in v2bf16 canonicalization

Signed-off-by: John Lu <John.Lu at amd.com>
---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  5 +-
 .../test/CodeGen/AMDGPU/fcanonicalize.bf16.ll | 88 ++++++++++++-------
 2 files changed, 58 insertions(+), 35 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 72774c7ea97b0..be134704b31af 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -16392,8 +16392,9 @@ SITargetLowering::performFCanonicalizeCombine(SDNode *N,
 
   // TODO: This could be better with wider vectors that will be split to v2f16,
   // and to consider uses since there aren't that many packed operations.
-  if (N0.getOpcode() == ISD::BUILD_VECTOR && VT == MVT::v2f16 &&
-      isTypeLegal(MVT::v2f16)) {
+  if (N0.getOpcode() == ISD::BUILD_VECTOR &&
+      (VT == MVT::v2f16 || VT == MVT::v2bf16) &&
+      isTypeLegal(VT)) {
     SDLoc SL(N);
     SDValue NewElts[2];
     SDValue Lo = N0.getOperand(0);
diff --git a/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll b/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
index 93893346c0604..d10c840993aa9 100644
--- a/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
+++ b/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
@@ -1087,12 +1087,22 @@ define amdgpu_kernel void @s_test_canonicalize_undef_v2bf16(ptr addrspace(1) %ou
 }
 
 define <2 x bfloat> @v_test_canonicalize_reg_undef_v2bf16(bfloat %val) #1 {
-; GFX1250-LABEL: v_test_canonicalize_reg_undef_v2bf16:
-; GFX1250:       ; %bb.0:
-; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
-; GFX1250-NEXT:    s_wait_kmcnt 0x0
-; GFX1250-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; GFX1250-NEXT:    s_set_pc_i64 s[30:31]
+; FAKE16-LABEL: v_test_canonicalize_reg_undef_v2bf16:
+; FAKE16:       ; %bb.0:
+; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
+; FAKE16-NEXT:    s_wait_kmcnt 0x0
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
+; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
+;
+; REAL16-LABEL: v_test_canonicalize_reg_undef_v2bf16:
+; REAL16:       ; %bb.0:
+; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
+; REAL16-NEXT:    s_wait_kmcnt 0x0
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
+; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <2 x bfloat> poison, bfloat %val, i32 0
   %canonicalized = call <2 x bfloat> @llvm.canonicalize.v2bf16(<2 x bfloat> %vec)
   ret <2 x bfloat> %canonicalized
@@ -1103,18 +1113,19 @@ define <2 x bfloat> @v_test_canonicalize_undef_reg_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; FAKE16-NEXT:    v_perm_b32 v0, v0, 0, 0x5040100
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_undef_reg_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, v0.l
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_mov_b16_e32 v0.l, 0
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, v1.l
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <2 x bfloat> poison, bfloat %val, i32 1
   %canonicalized = call <2 x bfloat> @llvm.canonicalize.v2bf16(<2 x bfloat> %vec)
@@ -1174,20 +1185,18 @@ define <2 x bfloat> @v_test_canonicalize_reg_k_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_movk_i32 s0, 0x4000
-; FAKE16-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
 ; FAKE16-NEXT:    v_perm_b32 v0, s0, v0, 0x5040100
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_reg_k_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_mov_b16_e32 v1.h, 0x4000
-; REAL16-NEXT:    v_mov_b16_e32 v1.l, v0.l
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v1 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0x4000
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <2 x bfloat> poison, bfloat %val, i32 0
   %vec1 = insertelement <2 x bfloat> %vec0, bfloat 2.0, i32 1
@@ -1200,20 +1209,20 @@ define <2 x bfloat> @v_test_canonicalize_k_reg_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_movk_i32 s0, 0x4000
-; FAKE16-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
 ; FAKE16-NEXT:    v_perm_b32 v0, v0, s0, 0x5040100
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_k_reg_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_mov_b16_e32 v1.l, 0x4000
-; REAL16-NEXT:    v_mov_b16_e32 v1.h, v0.l
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v1 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_mov_b16_e32 v0.l, 0x4000
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, v1.l
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <2 x bfloat> poison, bfloat 2.0, i32 0
   %vec1 = insertelement <2 x bfloat> %vec0, bfloat %val, i32 1
@@ -1240,13 +1249,24 @@ define amdgpu_kernel void @s_test_canonicalize_undef_v4bf16(ptr addrspace(1) %ou
 }
 
 define <4 x bfloat> @v_test_canonicalize_reg_undef_undef_undef_v4bf16(bfloat %val) #1 {
-; GFX1250-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
-; GFX1250:       ; %bb.0:
-; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
-; GFX1250-NEXT:    s_wait_kmcnt 0x0
-; GFX1250-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; GFX1250-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
-; GFX1250-NEXT:    s_set_pc_i64 s[30:31]
+; FAKE16-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
+; FAKE16:       ; %bb.0:
+; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
+; FAKE16-NEXT:    s_wait_kmcnt 0x0
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; FAKE16-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
+; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
+;
+; REAL16-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
+; REAL16:       ; %bb.0:
+; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
+; REAL16-NEXT:    s_wait_kmcnt 0x0
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
+; REAL16-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
+; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <4 x bfloat> poison, bfloat %val, i32 0
   %canonicalized = call <4 x bfloat> @llvm.canonicalize.v4bf16(<4 x bfloat> %vec)
   ret <4 x bfloat> %canonicalized
@@ -1283,9 +1303,10 @@ define <4 x bfloat> @v_test_canonicalize_reg_undef_reg_reg_v4bf16(bfloat %val0,
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_perm_b32 v1, v2, v1, 0x5040100
 ; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; FAKE16-NEXT:    v_perm_b32 v1, v2, v1, 0x5040100
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
 ; FAKE16-NEXT:    v_pk_mul_bf16 v1, 1.0, v1 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
@@ -1295,7 +1316,8 @@ define <4 x bfloat> @v_test_canonicalize_reg_undef_reg_reg_v4bf16(bfloat %val0,
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
 ; REAL16-NEXT:    v_mov_b16_e32 v1.h, v2.l
 ; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_3)
 ; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v1 op_sel_hi:[0,1]
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <4 x bfloat> poison, bfloat %val0, i32 0

>From 821bfd1f4b242a6bbf1c05e1b47f079433998f70 Mon Sep 17 00:00:00 2001
From: John Lu <John.Lu at amd.com>
Date: Wed, 5 Aug 2026 21:31:35 -0500
Subject: [PATCH 2/3] Fix formatting

Signed-off-by: John Lu <John.Lu at amd.com>
---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index be134704b31af..016278779b2fe 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -16393,8 +16393,7 @@ SITargetLowering::performFCanonicalizeCombine(SDNode *N,
   // TODO: This could be better with wider vectors that will be split to v2f16,
   // and to consider uses since there aren't that many packed operations.
   if (N0.getOpcode() == ISD::BUILD_VECTOR &&
-      (VT == MVT::v2f16 || VT == MVT::v2bf16) &&
-      isTypeLegal(VT)) {
+      (VT == MVT::v2f16 || VT == MVT::v2bf16) && isTypeLegal(VT)) {
     SDLoc SL(N);
     SDValue NewElts[2];
     SDValue Lo = N0.getOperand(0);

>From bf54b78d8856bee554335062057d091977f22ce5 Mon Sep 17 00:00:00 2001
From: John Lu <John.Lu at amd.com>
Date: Fri, 7 Aug 2026 20:10:57 -0500
Subject: [PATCH 3/3] Only convert if scalar canonicalization insn exists

Signed-off-by: John Lu <John.Lu at amd.com>
---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  8 +-
 .../test/CodeGen/AMDGPU/fcanonicalize.bf16.ll | 88 +++++++------------
 2 files changed, 40 insertions(+), 56 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 016278779b2fe..017e0f5ebc83e 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -16393,13 +16393,19 @@ SITargetLowering::performFCanonicalizeCombine(SDNode *N,
   // TODO: This could be better with wider vectors that will be split to v2f16,
   // and to consider uses since there aren't that many packed operations.
   if (N0.getOpcode() == ISD::BUILD_VECTOR &&
-      (VT == MVT::v2f16 || VT == MVT::v2bf16) && isTypeLegal(VT)) {
+      VT.getVectorNumElements() == 2 && isTypeLegal(VT)) {
     SDLoc SL(N);
     SDValue NewElts[2];
     SDValue Lo = N0.getOperand(0);
     SDValue Hi = N0.getOperand(1);
     EVT EltVT = Lo.getValueType();
 
+    // Only apply this optimization if scalar canonicalize is legal for the
+    // element type. Otherwise, scalarizing may require widening the scalar back
+    // to a vector, adding overhead (e.g., bf16 has no scalar instructions).
+    if (getOperationAction(ISD::FCANONICALIZE, EltVT) != Legal)
+      return SDValue();
+
     if (vectorEltWillFoldAway(Lo) || vectorEltWillFoldAway(Hi)) {
       for (unsigned I = 0; I != 2; ++I) {
         SDValue Op = N0.getOperand(I);
diff --git a/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll b/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
index d10c840993aa9..93893346c0604 100644
--- a/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
+++ b/llvm/test/CodeGen/AMDGPU/fcanonicalize.bf16.ll
@@ -1087,22 +1087,12 @@ define amdgpu_kernel void @s_test_canonicalize_undef_v2bf16(ptr addrspace(1) %ou
 }
 
 define <2 x bfloat> @v_test_canonicalize_reg_undef_v2bf16(bfloat %val) #1 {
-; FAKE16-LABEL: v_test_canonicalize_reg_undef_v2bf16:
-; FAKE16:       ; %bb.0:
-; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
-; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
-; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
-;
-; REAL16-LABEL: v_test_canonicalize_reg_undef_v2bf16:
-; REAL16:       ; %bb.0:
-; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
-; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
-; REAL16-NEXT:    s_set_pc_i64 s[30:31]
+; GFX1250-LABEL: v_test_canonicalize_reg_undef_v2bf16:
+; GFX1250:       ; %bb.0:
+; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; GFX1250-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <2 x bfloat> poison, bfloat %val, i32 0
   %canonicalized = call <2 x bfloat> @llvm.canonicalize.v2bf16(<2 x bfloat> %vec)
   ret <2 x bfloat> %canonicalized
@@ -1113,19 +1103,18 @@ define <2 x bfloat> @v_test_canonicalize_undef_reg_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; FAKE16-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
 ; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; FAKE16-NEXT:    v_perm_b32 v0, v0, 0, 0x5040100
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_undef_reg_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.l, 0
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, v1.l
+; REAL16-NEXT:    v_mov_b16_e32 v0.h, v0.l
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <2 x bfloat> poison, bfloat %val, i32 1
   %canonicalized = call <2 x bfloat> @llvm.canonicalize.v2bf16(<2 x bfloat> %vec)
@@ -1185,18 +1174,20 @@ define <2 x bfloat> @v_test_canonicalize_reg_k_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_movk_i32 s0, 0x4000
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; FAKE16-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; FAKE16-NEXT:    v_perm_b32 v0, s0, v0, 0x5040100
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_reg_k_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0x4000
+; REAL16-NEXT:    v_mov_b16_e32 v1.h, 0x4000
+; REAL16-NEXT:    v_mov_b16_e32 v1.l, v0.l
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v1 op_sel_hi:[0,1]
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <2 x bfloat> poison, bfloat %val, i32 0
   %vec1 = insertelement <2 x bfloat> %vec0, bfloat 2.0, i32 1
@@ -1209,20 +1200,20 @@ define <2 x bfloat> @v_test_canonicalize_k_reg_v2bf16(bfloat %val) #1 {
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_movk_i32 s0, 0x4000
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; FAKE16-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; FAKE16-NEXT:    v_perm_b32 v0, v0, s0, 0x5040100
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
 ; REAL16-LABEL: v_test_canonicalize_k_reg_v2bf16:
 ; REAL16:       ; %bb.0:
 ; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.l, 0x4000
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, v1.l
+; REAL16-NEXT:    v_mov_b16_e32 v1.l, 0x4000
+; REAL16-NEXT:    v_mov_b16_e32 v1.h, v0.l
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v1 op_sel_hi:[0,1]
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <2 x bfloat> poison, bfloat 2.0, i32 0
   %vec1 = insertelement <2 x bfloat> %vec0, bfloat %val, i32 1
@@ -1249,24 +1240,13 @@ define amdgpu_kernel void @s_test_canonicalize_undef_v4bf16(ptr addrspace(1) %ou
 }
 
 define <4 x bfloat> @v_test_canonicalize_reg_undef_undef_undef_v4bf16(bfloat %val) #1 {
-; FAKE16-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
-; FAKE16:       ; %bb.0:
-; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
-; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; FAKE16-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
-; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
-;
-; REAL16-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
-; REAL16:       ; %bb.0:
-; REAL16-NEXT:    s_wait_loadcnt_dscnt 0x0
-; REAL16-NEXT:    s_wait_kmcnt 0x0
-; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
-; REAL16-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
-; REAL16-NEXT:    s_set_pc_i64 s[30:31]
+; GFX1250-LABEL: v_test_canonicalize_reg_undef_undef_undef_v4bf16:
+; GFX1250:       ; %bb.0:
+; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; GFX1250-NEXT:    v_mov_b32_e32 v1, 0x7fc07fc0
+; GFX1250-NEXT:    s_set_pc_i64 s[30:31]
   %vec = insertelement <4 x bfloat> poison, bfloat %val, i32 0
   %canonicalized = call <4 x bfloat> @llvm.canonicalize.v4bf16(<4 x bfloat> %vec)
   ret <4 x bfloat> %canonicalized
@@ -1303,10 +1283,9 @@ define <4 x bfloat> @v_test_canonicalize_reg_undef_reg_reg_v4bf16(bfloat %val0,
 ; FAKE16:       ; %bb.0:
 ; FAKE16-NEXT:    s_wait_loadcnt_dscnt 0x0
 ; FAKE16-NEXT:    s_wait_kmcnt 0x0
-; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    v_perm_b32 v1, v2, v1, 0x5040100
-; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; FAKE16-NEXT:    v_perm_b32 v0, 0, v0, 0x5040100
+; FAKE16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
+; FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
 ; FAKE16-NEXT:    v_pk_mul_bf16 v1, 1.0, v1 op_sel_hi:[0,1]
 ; FAKE16-NEXT:    s_set_pc_i64 s[30:31]
 ;
@@ -1316,8 +1295,7 @@ define <4 x bfloat> @v_test_canonicalize_reg_undef_reg_reg_v4bf16(bfloat %val0,
 ; REAL16-NEXT:    s_wait_kmcnt 0x0
 ; REAL16-NEXT:    v_mov_b16_e32 v1.h, v2.l
 ; REAL16-NEXT:    v_pk_mul_bf16 v0, 1.0, v0 op_sel_hi:[0,1]
-; REAL16-NEXT:    v_mov_b16_e32 v0.h, 0
-; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_3)
+; REAL16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
 ; REAL16-NEXT:    v_pk_mul_bf16 v1, 1.0, v1 op_sel_hi:[0,1]
 ; REAL16-NEXT:    s_set_pc_i64 s[30:31]
   %vec0 = insertelement <4 x bfloat> poison, bfloat %val0, i32 0



More information about the llvm-commits mailing list