[llvm] [AMDGPU] Mark V_PK_MOV_B32 as not commutable (PR #217719)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 11:20:28 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/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
>From e068e548a577303acf837a118e3c76028134681a Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 20 Aug 2026 20:04:04 +0200
Subject: [PATCH] [AMDGPU] Mark V_PK_MOV_B32 as not commutable
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
---
llvm/lib/Target/AMDGPU/VOP3PInstructions.td | 3 +-
.../machine-cse-commute-target-flags.mir | 31 +++++++++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)
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..5850d50a2cfd1 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,7 @@
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 }
declare void @func()
@gv = external addrspace(1) global i32
@@ -120,3 +122,32 @@ 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
+
+...
More information about the llvm-commits
mailing list