[llvm] c37df50 - [AMDGPU] Mark V_PK_MOV_B32 as not commutable (#217719)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 08:39:41 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-08-28T17:39:36+02:00
New Revision: c37df50add94eb53739eb82462f4b2ead8564fcb

URL: https://github.com/llvm/llvm-project/commit/c37df50add94eb53739eb82462f4b2ead8564fcb
DIFF: https://github.com/llvm/llvm-project/commit/c37df50add94eb53739eb82462f4b2ead8564fcb.diff

LOG: [AMDGPU] Mark V_PK_MOV_B32 as not commutable (#217719)

Its result halves are positional (dst.lo from src0, dst.hi from src1),
so MachineCSE commuting the operands and CSE'ing the result silently
swaps the halves, miscompiling the code

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/VOP3PInstructions.td
    llvm/test/CodeGen/AMDGPU/machine-cse-commute-target-flags.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
index 807d52eb0cdbb..b5dc87861fd33 100644
--- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
@@ -1453,7 +1453,8 @@ let isCommutable = 1, isReMaterializable = 1 in {
     defm V_PK_ADD_F32_gfx1250 : VOP3PInst<"v_pk_add_f32", VOP3P_Profile<VOP_V2F32_V2F32_V2F32, VOP3_PACKED>, any_fadd>;
   }
 
-  let SubtargetPredicate = HasPkMovB32, isAsCheapAsAMove = 1 in
+  let SubtargetPredicate = HasPkMovB32, isAsCheapAsAMove = 1,
+      isCommutable = 0 in
   defm V_PK_MOV_B32 : VOP3PInst<"v_pk_mov_b32", VOP3P_Profile<VOP_V2I32_V2I32_V2I32, VOP3_PACKED>>;
 
   let SubtargetPredicate = HasBF16PackedInsts in {

diff  --git a/llvm/test/CodeGen/AMDGPU/machine-cse-commute-target-flags.mir b/llvm/test/CodeGen/AMDGPU/machine-cse-commute-target-flags.mir
index 80733cc8422c2..13346ad2bb259 100644
--- a/llvm/test/CodeGen/AMDGPU/machine-cse-commute-target-flags.mir
+++ b/llvm/test/CodeGen/AMDGPU/machine-cse-commute-target-flags.mir
@@ -1,6 +1,7 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple=amdgpu10.10-amd-amdhsa -run-pass=machine-cse -o - %s | FileCheck %s
 # RUN: llc -mtriple=amdgpu11.00-amd-amdhsa -run-pass=machine-cse -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.0a-amd-amdhsa -run-pass=machine-cse -o - %s | FileCheck %s
 
 --- |
   define void @commute_instruction_subreg_target_flag() { ret void }
@@ -8,6 +9,8 @@
   define void @commute_target_flag_global() { ret void }
   define void @commute_target_flag_global_offset() { ret void }
   define void @commute_target_flag_global_offset_mismatch() { ret void }
+  define void @pk_mov_no_cse() { ret void }
+  define void @pk_mov_cse_identical() { ret void }
 
   declare void @func()
   @gv = external addrspace(1) global i32
@@ -120,3 +123,60 @@ body:             |
     S_ENDPGM 0, implicit %1, implicit %2
 
 ...
+
+---
+name:            pk_mov_no_cse
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4_vgpr5
+
+    ; CHECK-LABEL: name: pk_mov_no_cse
+    ; CHECK: liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4_vgpr5
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vreg_64_align2 = COPY $vgpr0_vgpr1
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vreg_64_align2 = COPY $vgpr2_vgpr3
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vreg_64_align2 = COPY $vgpr4_vgpr5
+    ; CHECK-NEXT: [[V_PK_MOV_B32_:%[0-9]+]]:vreg_64_align2 = V_PK_MOV_B32 12, [[COPY]], 8, [[COPY1]], 0, 0, 0, 0, 0, implicit $exec
+    ; CHECK-NEXT: [[V_PK_MOV_B32_1:%[0-9]+]]:vreg_64_align2 = V_PK_MOV_B32 8, [[COPY1]], 12, [[COPY]], 0, 0, 0, 0, 0, implicit $exec
+    ; CHECK-NEXT: GLOBAL_STORE_DWORDX2 [[COPY2]], [[V_PK_MOV_B32_]], 0, 0, implicit $exec :: (store (s64), addrspace 1)
+    ; CHECK-NEXT: GLOBAL_STORE_DWORDX2 [[COPY2]], [[V_PK_MOV_B32_1]], 8, 0, implicit $exec :: (store (s64), addrspace 1)
+    ; CHECK-NEXT: SI_RETURN
+    %0:vreg_64_align2 = COPY $vgpr0_vgpr1
+    %1:vreg_64_align2 = COPY $vgpr2_vgpr3
+    %2:vreg_64_align2 = COPY $vgpr4_vgpr5
+    %4:vreg_64_align2 = V_PK_MOV_B32 12, %0, 8, %1, 0, 0, 0, 0, 0, implicit $exec
+    %5:vreg_64_align2 = V_PK_MOV_B32 8, %1, 12, %0, 0, 0, 0, 0, 0, implicit $exec
+    GLOBAL_STORE_DWORDX2 %2, %4, 0, 0, implicit $exec :: (store (s64), addrspace 1)
+    GLOBAL_STORE_DWORDX2 %2, %5, 8, 0, implicit $exec :: (store (s64), addrspace 1)
+    SI_RETURN
+
+...
+
+---
+name:            pk_mov_cse_identical
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4_vgpr5
+
+    ; CHECK-LABEL: name: pk_mov_cse_identical
+    ; CHECK: liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4_vgpr5
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vreg_64_align2 = COPY $vgpr0_vgpr1
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vreg_64_align2 = COPY $vgpr2_vgpr3
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vreg_64_align2 = COPY $vgpr4_vgpr5
+    ; CHECK-NEXT: [[V_PK_MOV_B32_:%[0-9]+]]:vreg_64_align2 = V_PK_MOV_B32 12, [[COPY]], 8, [[COPY1]], 0, 0, 0, 0, 0, implicit $exec
+    ; CHECK-NEXT: GLOBAL_STORE_DWORDX2 [[COPY2]], [[V_PK_MOV_B32_]], 0, 0, implicit $exec :: (store (s64), addrspace 1)
+    ; CHECK-NEXT: GLOBAL_STORE_DWORDX2 [[COPY2]], [[V_PK_MOV_B32_]], 8, 0, implicit $exec :: (store (s64), addrspace 1)
+    ; CHECK-NEXT: SI_RETURN
+    %0:vreg_64_align2 = COPY $vgpr0_vgpr1
+    %1:vreg_64_align2 = COPY $vgpr2_vgpr3
+    %2:vreg_64_align2 = COPY $vgpr4_vgpr5
+    %4:vreg_64_align2 = V_PK_MOV_B32 12, %0, 8, %1, 0, 0, 0, 0, 0, implicit $exec
+    %5:vreg_64_align2 = V_PK_MOV_B32 12, %0, 8, %1, 0, 0, 0, 0, 0, implicit $exec
+    GLOBAL_STORE_DWORDX2 %2, %4, 0, 0, implicit $exec :: (store (s64), addrspace 1)
+    GLOBAL_STORE_DWORDX2 %2, %5, 8, 0, implicit $exec :: (store (s64), addrspace 1)
+    SI_RETURN
+
+...


        


More information about the llvm-commits mailing list