[llvm] [CodeGenPrepare] Failure to hoist bitcast to legal type causes register splitting (PR #207568)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 5 02:23:43 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-backend-arm

Author: 黃國庭 (houngkoungting)

<details>
<summary>Changes</summary>

FIX #<!-- -->179950 
Hi @<!-- -->RKSimon 
Thanks for the guidance! Following your suggestion, I've extracted the core logic from CodeGenPrepare.cpp into a new optimizeBitCast function. It  works perfectly to prevent the register splitting issue.

I have also included tests covering both legal and illegal types.

(Note: I closed the previous PR because its commit history became cluttered. This is a brand new, clean pull request for a proper review path.)

Could you please take a look when you have free time? Thanks!


I wanted to push this first to see if it passes the CI. A small part of the logic is currently a bit hardcoded, and I'm not sure if it's entirely appropriate, so I'd love to get your feedback on that. Thanks!


BR 

HKT

---

Patch is 63.34 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/207568.diff


4 Files Affected:

- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+64) 
- (modified) llvm/test/CodeGen/ARM/aes-erratum-fix.ll (+414-528) 
- (added) llvm/test/Transforms/CodeGenPrepare/X86/hoist-bitcast-i686.ll (+27) 
- (added) llvm/test/Transforms/CodeGenPrepare/X86/hoist-bitcast-integer-to-vector.ll (+63) 


``````````diff
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index aa14d2586a534..16d6a5da54e66 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1488,6 +1488,61 @@ static bool SinkCast(CastInst *CI) {
   return MadeChange;
 }
 
+/// Hoists bitcasts to the source block to reduce register pressure
+static bool optimizeBitCast(BitCastInst *BCI, const TargetLowering &TLI,
+                            const DataLayout &DL) {
+  auto *SrcInst = dyn_cast<Instruction>(BCI->getOperand(0));
+  if (!SrcInst || SrcInst->getParent() == BCI->getParent() ||
+      SrcInst->isTerminator())
+    return false;
+
+  EVT SrcVT = TLI.getValueType(DL, SrcInst->getType());
+  EVT DestVT = TLI.getValueType(DL, BCI->getType());
+
+  // Bail out on scalable vectors and illegal destination types
+  if (SrcVT.isScalableVector() || DestVT.isScalableVector() ||
+      !TLI.isTypeLegal(DestVT))
+    return false;
+
+  // Only hoist if it reduces physical register count
+  if (TLI.getNumRegisters(BCI->getContext(), SrcVT) <=
+      TLI.getNumRegisters(BCI->getContext(), DestVT))
+    return false;
+
+  // Prevent large cross-domain scalar hoists
+  Type *DestTy = BCI->getType();
+  Type *SrcTy = SrcInst->getType();
+  bool IsCrossDomain = DestTy->isFPOrFPVectorTy() != SrcTy->isFPOrFPVectorTy();
+  bool IsLargeScalar = !DestTy->isVectorTy() &&
+                       DL.getTypeSizeInBits(DestTy).getFixedValue() > 64;
+  if (IsCrossDomain && IsLargeScalar)
+    return false;
+
+  // SelectionDAG Guard to prevent breaking atomic loop layout
+  auto IsAtomic = [](const Value *V) {
+    const auto *I = dyn_cast<Instruction>(V);
+    return I && I->isAtomic();
+  };
+
+  // Check upstream atomic -> [extractvalue] -> bitcast
+  const Value *Origin = SrcInst;
+  if (auto *EV = dyn_cast<ExtractValueInst>(Origin))
+    Origin = EV->getAggregateOperand();
+
+  // Check downstream bitcast -> [phi] -> atomic
+  if (IsAtomic(Origin) || any_of(BCI->users(), [IsAtomic](const User *U) {
+        return IsAtomic(U) || (isa<PHINode>(U) && any_of(U->users(), IsAtomic));
+      }))
+    return false;
+
+  // Hoist the bitcast
+  BasicBlock *SrcBB = SrcInst->getParent();
+  auto InsertPt = isa<PHINode>(SrcInst) ? SrcBB->getFirstInsertionPt()
+                                        : std::next(SrcInst->getIterator());
+  BCI->moveBefore(*SrcBB, InsertPt);
+  return true;
+}
+
 /// If the specified cast instruction is a noop copy (e.g. it's casting from
 /// one pointer type to another, i32->i8 on PPC), sink it into user blocks to
 /// reduce the number of virtual registers that must be created and coalesced.
@@ -8938,6 +8993,15 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) {
     // evaluation in a block other than then one that uses it (e.g. to hoist
     // the address of globals out of a loop).  If this is the case, we don't
     // want to forward-subst the cast.
+    
+    if (auto *BCI = dyn_cast<BitCastInst>(CI)) {
+      // Hoist bitcasts of illegal types to reduce cross-block register pressure
+      // and prevent register splitting.
+      if (optimizeBitCast(BCI, *TLI, *DL)) {
+        return true;        
+      }
+    }
+
     if (isa<Constant>(CI->getOperand(0)))
       return AnyChange;
 
diff --git a/llvm/test/CodeGen/ARM/aes-erratum-fix.ll b/llvm/test/CodeGen/ARM/aes-erratum-fix.ll
index 82f5bfd02a56e..9cec607eae096 100644
--- a/llvm/test/CodeGen/ARM/aes-erratum-fix.ll
+++ b/llvm/test/CodeGen/ARM/aes-erratum-fix.ll
@@ -1353,38 +1353,22 @@ define arm_aapcs_vfpcc void @aese_setf16_via_val(half %0, <16 x i8> %1, ptr %2)
 define arm_aapcs_vfpcc void @aese_setf16_cond_via_ptr(i1 zeroext %0, ptr %1, <16 x i8> %2, ptr %3) nounwind {
 ; CHECK-FIX-NOSCHED-LABEL: aese_setf16_cond_via_ptr:
 ; CHECK-FIX-NOSCHED:       @ %bb.0:
-; CHECK-FIX-NOSCHED-NEXT:    .save {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-FIX-NOSCHED-NEXT:    push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-FIX-NOSCHED-NEXT:    .pad #12
-; CHECK-FIX-NOSCHED-NEXT:    sub sp, sp, #12
+; CHECK-FIX-NOSCHED-NEXT:    .save {r4, r5, r6, r7, r8, lr}
+; CHECK-FIX-NOSCHED-NEXT:    push {r4, r5, r6, r7, r8, lr}
 ; CHECK-FIX-NOSCHED-NEXT:    cmp r0, #0
-; CHECK-FIX-NOSCHED-NEXT:    beq .LBB36_3
+; CHECK-FIX-NOSCHED-NEXT:    beq .LBB36_2
 ; CHECK-FIX-NOSCHED-NEXT:  @ %bb.1:
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.64 {d16, d17}, [r2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d17[3]
 ; CHECK-FIX-NOSCHED-NEXT:    ldrh r7, [r1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r9, d17[0]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r10, d16[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r11, d16[2]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp, #8] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[2]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp, #4] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[1]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp] @ 4-byte Spill
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d17[2]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d17[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d17[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d16[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d16[2]
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d16[1]
-; CHECK-FIX-NOSCHED-NEXT:    cmp r0, #0
-; CHECK-FIX-NOSCHED-NEXT:    bne .LBB36_4
+; CHECK-FIX-NOSCHED-NEXT:    b .LBB36_3
 ; CHECK-FIX-NOSCHED-NEXT:  .LBB36_2:
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r0, d1[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d1[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d1[1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d1[0]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d0[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d0[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d0[1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r1, d0[0]
-; CHECK-FIX-NOSCHED-NEXT:    b .LBB36_5
-; CHECK-FIX-NOSCHED-NEXT:  .LBB36_3:
 ; CHECK-FIX-NOSCHED-NEXT:    add r3, r2, #8
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d16[0]}, [r2:32]
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d17[0]}, [r3:32]
@@ -1392,144 +1376,125 @@ define arm_aapcs_vfpcc void @aese_setf16_cond_via_ptr(i1 zeroext %0, ptr %1, <16
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d16[1]}, [r3:32]
 ; CHECK-FIX-NOSCHED-NEXT:    add r3, r2, #12
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d17[1]}, [r3:32]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r9, d17[0]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r10, d16[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r11, d16[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d16[0]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp, #8] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[2]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp, #4] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[1]
-; CHECK-FIX-NOSCHED-NEXT:    str r3, [sp] @ 4-byte Spill
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d17[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d17[2]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d17[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d17[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d16[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d16[2]
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d16[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d16[0]
+; CHECK-FIX-NOSCHED-NEXT:  .LBB36_3:
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r3, r7, r3, lsl #16
 ; CHECK-FIX-NOSCHED-NEXT:    cmp r0, #0
-; CHECK-FIX-NOSCHED-NEXT:    beq .LBB36_2
-; CHECK-FIX-NOSCHED-NEXT:  .LBB36_4:
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r0, d1[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d16[0], r3
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r3, r4, r8, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d17[0], r3
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r3, r6, r5, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d16[1], r3
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r3, lr, r12, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d17[1], r3
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d1[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d1[2]
+; CHECK-FIX-NOSCHED-NEXT:    beq .LBB36_5
+; CHECK-FIX-NOSCHED-NEXT:  @ %bb.4:
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r0, d1[1]
 ; CHECK-FIX-NOSCHED-NEXT:    ldrh r1, [r1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d1[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d1[1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d1[0]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d0[3]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d0[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d0[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d1[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d0[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d0[2]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d0[1]
+; CHECK-FIX-NOSCHED-NEXT:    b .LBB36_6
 ; CHECK-FIX-NOSCHED-NEXT:  .LBB36_5:
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, r1, r8, lsl #16
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r3, r7, r3, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r0, d1[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d1[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d0[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d0[2]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d0[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r1, d0[0]
+; CHECK-FIX-NOSCHED-NEXT:  .LBB36_6:
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, r1, r7, lsl #16
 ; CHECK-FIX-NOSCHED-NEXT:    pkhbt r0, r4, r0, lsl #16
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d18[0], r1
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, lr, r12, lsl #16
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d16[0], r3
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d18[1], r1
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, r11, r10, lsl #16
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d16[1], r1
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, r6, r5, lsl #16
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d19[0], r1
-; CHECK-FIX-NOSCHED-NEXT:    ldr r1, [sp] @ 4-byte Reload
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r1, r9, r1, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d19[0], r0
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r0, r6, r5, lsl #16
+; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d18[1], r0
+; CHECK-FIX-NOSCHED-NEXT:    pkhbt r0, r3, r12, lsl #16
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d19[1], r0
-; CHECK-FIX-NOSCHED-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d17[0], r1
-; CHECK-FIX-NOSCHED-NEXT:    ldr r1, [sp, #4] @ 4-byte Reload
-; CHECK-FIX-NOSCHED-NEXT:    pkhbt r0, r1, r0, lsl #16
-; CHECK-FIX-NOSCHED-NEXT:    vmov.32 d17[1], r0
 ; CHECK-FIX-NOSCHED-NEXT:    aese.8 q8, q9
 ; CHECK-FIX-NOSCHED-NEXT:    aesmc.8 q8, q8
 ; CHECK-FIX-NOSCHED-NEXT:    vst1.64 {d16, d17}, [r2]
-; CHECK-FIX-NOSCHED-NEXT:    add sp, sp, #12
-; CHECK-FIX-NOSCHED-NEXT:    pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
+; CHECK-FIX-NOSCHED-NEXT:    pop {r4, r5, r6, r7, r8, pc}
 ;
 ; CHECK-CORTEX-FIX-LABEL: aese_setf16_cond_via_ptr:
 ; CHECK-CORTEX-FIX:       @ %bb.0:
-; CHECK-CORTEX-FIX-NEXT:    .save {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-CORTEX-FIX-NEXT:    push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-CORTEX-FIX-NEXT:    .pad #24
-; CHECK-CORTEX-FIX-NEXT:    sub sp, sp, #24
+; CHECK-CORTEX-FIX-NEXT:    .save {r4, r5, r6, r7, r8, lr}
+; CHECK-CORTEX-FIX-NEXT:    push {r4, r5, r6, r7, r8, lr}
 ; CHECK-CORTEX-FIX-NEXT:    cmp r0, #0
-; CHECK-CORTEX-FIX-NEXT:    beq .LBB36_3
+; CHECK-CORTEX-FIX-NEXT:    beq .LBB36_2
 ; CHECK-CORTEX-FIX-NEXT:  @ %bb.1:
 ; CHECK-CORTEX-FIX-NEXT:    vld1.64 {d16, d17}, [r2]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[1]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r6, d17[0]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d17[2]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r4, d17[3]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #20] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[2]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #8] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[3]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #4] @ 4-byte Spill
+; CHECK-CORTEX-FIX-NEXT:    ldrh r4, [r1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r8, d16[1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r12, d16[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 lr, d16[3]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d17[0]
 ; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d17[1]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #12] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    ldrh r3, [r1]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #16] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    mov r3, r6
-; CHECK-CORTEX-FIX-NEXT:    cmp r0, #0
-; CHECK-CORTEX-FIX-NEXT:    bne .LBB36_4
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r5, d17[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r6, d17[3]
+; CHECK-CORTEX-FIX-NEXT:    b .LBB36_3
 ; CHECK-CORTEX-FIX-NEXT:  .LBB36_2:
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r0, d0[0]
-; CHECK-CORTEX-FIX-NEXT:    b .LBB36_5
-; CHECK-CORTEX-FIX-NEXT:  .LBB36_3:
-; CHECK-CORTEX-FIX-NEXT:    vld1.32 {d16[0]}, [r2:32]
 ; CHECK-CORTEX-FIX-NEXT:    add r3, r2, #8
+; CHECK-CORTEX-FIX-NEXT:    vld1.32 {d16[0]}, [r2:32]
 ; CHECK-CORTEX-FIX-NEXT:    add r7, r2, #4
 ; CHECK-CORTEX-FIX-NEXT:    vld1.32 {d17[0]}, [r3:32]
 ; CHECK-CORTEX-FIX-NEXT:    add r3, r2, #12
 ; CHECK-CORTEX-FIX-NEXT:    vld1.32 {d16[1]}, [r7:32]
 ; CHECK-CORTEX-FIX-NEXT:    vld1.32 {d17[1]}, [r3:32]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[0]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d17[1]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r4, d17[3]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #16] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[1]
-; CHECK-CORTEX-FIX-NEXT:    str r7, [sp, #12] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d17[2]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #20] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[2]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #8] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d16[3]
-; CHECK-CORTEX-FIX-NEXT:    str r3, [sp, #4] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d17[0]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r4, d16[0]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r8, d16[1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r12, d16[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 lr, d16[3]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d17[0]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d17[1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r5, d17[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r6, d17[3]
+; CHECK-CORTEX-FIX-NEXT:  .LBB36_3:
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r3, r7, r3, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r4, r4, r8, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r7, r12, lr, lsl #16
 ; CHECK-CORTEX-FIX-NEXT:    cmp r0, #0
-; CHECK-CORTEX-FIX-NEXT:    beq .LBB36_2
-; CHECK-CORTEX-FIX-NEXT:  .LBB36_4:
-; CHECK-CORTEX-FIX-NEXT:    ldrh r0, [r1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d16[0], r4
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d17[0], r3
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r3, r5, r6, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d16[1], r7
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d17[1], r3
+; CHECK-CORTEX-FIX-NEXT:    beq .LBB36_5
+; CHECK-CORTEX-FIX-NEXT:  @ %bb.4:
+; CHECK-CORTEX-FIX-NEXT:    ldrh r3, [r1]
+; CHECK-CORTEX-FIX-NEXT:    b .LBB36_6
 ; CHECK-CORTEX-FIX-NEXT:  .LBB36_5:
-; CHECK-CORTEX-FIX-NEXT:    str r0, [sp] @ 4-byte Spill
-; CHECK-CORTEX-FIX-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    ldr r1, [sp, #4] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r9, r7, r4, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    ldr r4, [sp, #20] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r10, d0[1]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r6, d0[2]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r12, d0[3]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r11, d1[0]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r5, d1[1]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 lr, d1[2]
-; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r8, d1[3]
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r7, r0, r1, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    ldr r1, [sp, #12] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r0, lr, r8, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r6, r6, r12, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r5, r11, r5, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r1, r3, r1, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    ldr r3, [sp, #16] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r4, r3, r4, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    ldr r3, [sp] @ 4-byte Reload
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d18[0], r4
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d19[0], r1
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d18[1], r7
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d19[1], r9
-; CHECK-CORTEX-FIX-NEXT:    pkhbt r3, r3, r10, lsl #16
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d16[0], r3
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d17[0], r5
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d16[1], r6
-; CHECK-CORTEX-FIX-NEXT:    vmov.32 d17[1], r0
-; CHECK-CORTEX-FIX-NEXT:    aese.8 q9, q8
-; CHECK-CORTEX-FIX-NEXT:    aesmc.8 q8, q9
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r3, d0[0]
+; CHECK-CORTEX-FIX-NEXT:  .LBB36_6:
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r0, d0[1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r12, d0[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r1, d0[3]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r7, d1[0]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r4, d1[1]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r5, d1[2]
+; CHECK-CORTEX-FIX-NEXT:    vmov.u16 r6, d1[3]
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r0, r3, r0, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r7, r7, r4, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r1, r12, r1, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d18[0], r0
+; CHECK-CORTEX-FIX-NEXT:    pkhbt r0, r5, r6, lsl #16
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d19[0], r7
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d18[1], r1
+; CHECK-CORTEX-FIX-NEXT:    vmov.32 d19[1], r0
+; CHECK-CORTEX-FIX-NEXT:    aese.8 q8, q9
+; CHECK-CORTEX-FIX-NEXT:    aesmc.8 q8, q8
 ; CHECK-CORTEX-FIX-NEXT:    vst1.64 {d16, d17}, [r2]
-; CHECK-CORTEX-FIX-NEXT:    add sp, sp, #24
-; CHECK-CORTEX-FIX-NEXT:    pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
+; CHECK-CORTEX-FIX-NEXT:    pop {r4, r5, r6, r7, r8, pc}
   br i1 %0, label %5, label %12
 
 5:
@@ -1575,25 +1540,20 @@ define arm_aapcs_vfpcc void @aese_setf16_cond_via_ptr(i1 zeroext %0, ptr %1, <16
 define arm_aapcs_vfpcc void @aese_setf16_cond_via_val(i1 zeroext %0, half %1, <16 x i8> %2, ptr %3) nounwind {
 ; CHECK-FIX-NOSCHED-LABEL: aese_setf16_cond_via_val:
 ; CHECK-FIX-NOSCHED:       @ %bb.0:
-; CHECK-FIX-NOSCHED-NEXT:    .save {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-FIX-NOSCHED-NEXT:    push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-; CHECK-FIX-NOSCHED-NEXT:    .pad #12
-; CHECK-FIX-NOSCHED-NEXT:    sub sp, sp, #12
+; CHECK-FIX-NOSCHED-NEXT:    .save {r4, r5, r6, r7, r11, lr}
+; CHECK-FIX-NOSCHED-NEXT:    push {r4, r5, r6, r7, r11, lr}
 ; CHECK-FIX-NOSCHED-NEXT:    cmp r0, #0
 ; CHECK-FIX-NOSCHED-NEXT:    beq .LBB37_2
 ; CHECK-FIX-NOSCHED-NEXT:  @ %bb.1:
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.64 {d16, d17}, [r1]
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.f32 s2, s0
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d17[1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d17[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d17[3]
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d17[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r11, d16[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d16[1]
-; CHECK-FIX-NOSCHED-NEXT:    str r2, [sp, #8] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d17[0]
-; CHECK-FIX-NOSCHED-NEXT:    str r2, [sp, #4] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d16[3]
-; CHECK-FIX-NOSCHED-NEXT:    str r2, [sp] @ 4-byte Spill
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d17[1]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r3, d17[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r4, d16[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r5, d16[2]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r6, d16[1]
 ; CHECK-FIX-NOSCHED-NEXT:    b .LBB37_3
 ; CHECK-FIX-NOSCHED-NEXT:  .LBB37_2:
 ; CHECK-FIX-NOSCHED-NEXT:    add r2, r1, #8
@@ -1603,99 +1563,76 @@ define arm_aapcs_vfpcc void @aese_setf16_cond_via_val(i1 zeroext %0, half %1, <1
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d16[1]}, [r2:32]
 ; CHECK-FIX-NOSCHED-NEXT:    add r2, r1, #12
 ; CHECK-FIX-NOSCHED-NEXT:    vld1.32 {d17[1]}, [r2:32]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d17[1]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d17[3]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r7, d16[0]
+; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r12, d17[3]
 ; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 lr, d17[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r11, d16[2]
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r8, d16[1]
-; CHECK-FIX-NOSCHED-NEXT:    str r2, [sp, #8] @ 4-byte Spill
-; CHECK-FIX-NOSCHED-NEXT:    vmov.u16 r2, d17[0]...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/207568


More information about the llvm-commits mailing list