[llvm] 5ec036a - [AArch64] Protect against mismatching sizes in UMOV combine. (#202116)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 06:45:42 PDT 2026


Author: David Green
Date: 2026-06-09T14:45:36+01:00
New Revision: 5ec036aba1243801320611f23f644707496e69c9

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

LOG: [AArch64] Protect against mismatching sizes in UMOV combine. (#202116)

This fixes an issue from #199139 where a later revision was not checking
the connection between the size of the UMOV and the size of the store.
This adds a check, based on the register sizes and the memory size from
the MMO.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
    llvm/test/CodeGen/AArch64/ldst-opt-umov-fpr-store.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 2d9b8eb06b7cd..0bca89815365f 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -3101,7 +3101,7 @@ bool AArch64LoadStoreOpt::tryToReplaceUMOVStore(
   if (!FPRStoreOpc)
     return false;
 
-  if (StoreMI.hasOrderedMemoryRef())
+  if (StoreMI.hasOrderedMemoryRef() || StoreMI.memoperands().size() != 1)
     return false;
 
   MachineBasicBlock *MBB = StoreMI.getParent();
@@ -3141,6 +3141,10 @@ bool AArch64LoadStoreOpt::tryToReplaceUMOVStore(
   if (!UMOVMI)
     return false;
   MCPhysReg VecReg = UMOVMI->getOperand(1).getReg();
+  MCPhysReg FPRReg = TRI->getSubReg(VecReg, SubRegIdx);
+  if ((*StoreMI.memoperands_begin())->getSizeInBits() !=
+      TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(FPRReg)))
+    return false;
 
   // Check that no instruction between UMOV and store clobbers the vector
   // register.  Also track whether VecReg is killed anywhere from the UMOV
@@ -3163,7 +3167,6 @@ bool AArch64LoadStoreOpt::tryToReplaceUMOVStore(
   LLVM_DEBUG(dbgs() << "Folding UMOV + store: " << *UMOVMI << "  + "
                     << StoreMI);
 
-  MCPhysReg FPRReg = TRI->getSubReg(VecReg, SubRegIdx);
   auto MIB = BuildMI(*MBB, MBBI, StoreMI.getDebugLoc(), TII->get(FPRStoreOpc))
                  .addReg(FPRReg, getKillRegState(VecRegKilled));
   for (unsigned I = 1, E = StoreMI.getNumExplicitOperands(); I < E; ++I)

diff  --git a/llvm/test/CodeGen/AArch64/ldst-opt-umov-fpr-store.mir b/llvm/test/CodeGen/AArch64/ldst-opt-umov-fpr-store.mir
index 10699d06fdbb5..0cd7ee88d83a6 100644
--- a/llvm/test/CodeGen/AArch64/ldst-opt-umov-fpr-store.mir
+++ b/llvm/test/CodeGen/AArch64/ldst-opt-umov-fpr-store.mir
@@ -330,3 +330,21 @@ body:             |
     STRHHroW killed renamable $w8, killed renamable $x0, killed renamable $w1, 0, 0 :: (store (s16))
     RET undef $lr
 ...
+---
+# UMOVvi8_idx0 + STRWui != STRBui
+name:            umov_i8_to_i32_fpr_store
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $q0, $x0
+
+    ; CHECK-LABEL: name: umov_i8_to_i32_fpr_store
+    ; CHECK: liveins: $q0, $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $w8 = UMOVvi8_idx0 killed renamable $q0, 0
+    ; CHECK-NEXT: STRWui killed renamable $w8, killed renamable $x0, 0 :: (store (s32))
+    ; CHECK-NEXT: RET undef $lr
+    renamable $w8 = UMOVvi8_idx0 killed renamable $q0, 0
+    STRWui killed renamable $w8, killed renamable $x0, 0 :: (store (s32))
+    RET undef $lr
+...


        


More information about the llvm-commits mailing list