[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