[llvm] 0146d20 - [AArch64] Do not fold SP adjustments into pre-increment addr modes if it overflows the redzone.

Amara Emerson via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 24 09:56:13 PST 2021


Author: Amara Emerson
Date: 2021-02-24T09:55:48-08:00
New Revision: 0146d206317e1d40775621639a4dde7c43e0f433

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

LOG: [AArch64] Do not fold SP adjustments into pre-increment addr modes if it overflows the redzone.

Instead of outright disabling this completely with the noredzone attribute,
we only avoid doing the optimization if there are memory operations between
the adjustment and the load/store that the adjustment would be folded into.
This avoids the case of something like a stack cookie being corrupted if an
exception happens before the pre-increment to the SP occurs.

This also prevents the folding happening if we have a redzone, but the offset
being folded is above the redzone amount (128 bytes in this case).

rdar://73269336

Differential Revision: https://reviews.llvm.org/D95179

Added: 
    llvm/test/CodeGen/AArch64/ldst-nopreidx-sp-redzone.mir

Modified: 
    llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
    llvm/lib/Target/AArch64/AArch64ISelLowering.h
    llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index acfd1785d102..cf4152fad4d2 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -325,16 +325,20 @@ static StackOffset getSVEStackSize(const MachineFunction &MF) {
 bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
   if (!EnableRedZone)
     return false;
+
   // Don't use the red zone if the function explicitly asks us not to.
   // This is typically used for kernel code.
-  if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone))
+  const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
+  const unsigned RedZoneSize =
+      Subtarget.getTargetLowering()->getRedZoneSize(MF.getFunction());
+  if (!RedZoneSize)
     return false;
 
   const MachineFrameInfo &MFI = MF.getFrameInfo();
   const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
   uint64_t NumBytes = AFI->getLocalStackSize();
 
-  return !(MFI.hasCalls() || hasFP(MF) || NumBytes > 128 ||
+  return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize ||
            getSVEStackSize(MF));
 }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 4959c8c3d589..8360b76d3c40 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -16,6 +16,7 @@
 
 #include "AArch64.h"
 #include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/IR/CallingConv.h"
@@ -807,6 +808,13 @@ class AArch64TargetLowering : public TargetLowering {
   /// vector types this override can be removed.
   bool mergeStoresAfterLegalization(EVT VT) const override;
 
+  // If the platform/function should have a redzone, return the size in bytes.
+  unsigned getRedZoneSize(const Function &F) const {
+    if (F.hasFnAttribute(Attribute::NoRedZone))
+      return 0;
+    return 128;
+  }
+
 private:
   /// Keep a pointer to the AArch64Subtarget around so that we can
   /// make the right decision when generating code for 
diff erent targets.

diff  --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index ad180cb2935e..c56f4660bb1b 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AArch64InstrInfo.h"
+#include "AArch64MachineFunctionInfo.h"
 #include "AArch64Subtarget.h"
 #include "MCTargetDesc/AArch64AddressingModes.h"
 #include "llvm/ADT/BitVector.h"
@@ -1849,6 +1850,7 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
   MachineBasicBlock::iterator E = I->getParent()->end();
   MachineInstr &MemMI = *I;
   MachineBasicBlock::iterator MBBI = I;
+  MachineFunction &MF = *MemMI.getMF();
 
   Register BaseReg = getLdStBaseOp(MemMI).getReg();
   int Offset = getLdStOffsetOp(MemMI).getImm();
@@ -1876,11 +1878,16 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
     return E;
   }
 
+  const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
+  unsigned RedZoneSize =
+      Subtarget.getTargetLowering()->getRedZoneSize(MF.getFunction());
+
   // Track which register units have been modified and used between the first
   // insn (inclusive) and the second insn.
   ModifiedRegUnits.clear();
   UsedRegUnits.clear();
   unsigned Count = 0;
+  bool MemAcessBeforeSPPreInc = false;
   do {
     MBBI = prev_nodbg(MBBI, B);
     MachineInstr &MI = *MBBI;
@@ -1891,8 +1898,13 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
       ++Count;
 
     // If we found a match, return it.
-    if (isMatchingUpdateInsn(*I, MI, BaseReg, Offset))
+    if (isMatchingUpdateInsn(*I, MI, BaseReg, Offset)) {
+      // Check that the update value is within our red zone limit (which may be
+      // zero).
+      if (MemAcessBeforeSPPreInc && MBBI->getOperand(2).getImm() > RedZoneSize)
+        return E;
       return MBBI;
+    }
 
     // Update the status of what the instruction clobbered and used.
     LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits, UsedRegUnits, TRI);
@@ -1902,6 +1914,11 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
     if (!ModifiedRegUnits.available(BaseReg) ||
         !UsedRegUnits.available(BaseReg))
       return E;
+    // Keep track if we have a memory access before an SP pre-increment, in this
+    // case we need to validate later that the update amount respects the red
+    // zone.
+    if (BaseRegSP && MBBI->mayLoadOrStore())
+      MemAcessBeforeSPPreInc = true;
   } while (MBBI != B && Count < Limit);
   return E;
 }

diff  --git a/llvm/test/CodeGen/AArch64/ldst-nopreidx-sp-redzone.mir b/llvm/test/CodeGen/AArch64/ldst-nopreidx-sp-redzone.mir
new file mode 100644
index 000000000000..8c66937fe8e0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ldst-nopreidx-sp-redzone.mir
@@ -0,0 +1,407 @@
+# RUN: llc -mtriple=aarch64-apple-darwin -run-pass=aarch64-ldst-opt  -verify-machineinstrs  -o - %s | FileCheck %s
+
+--- |
+  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+  target triple = "arm64e-apple-ios13.0"
+  
+  %struct.widget = type { i64, i64, i32, i32, i64, i64, i64, i64, i64, i32, i32, i32, i16, i32, %struct.snork*, %struct.zot, %struct.zot, %struct.zot, %struct.zot, %struct.zot, i64, i64, i64, i32, i64, i32, i32, i32, i8*, %struct.baz, %struct.baz, i64, i64, %struct.snork*, %struct.zot, i32, i32, i32, i32, i32, i32, i32, [32 x i8], i64, i64, %struct.wombat, i32, i64, i64, i64, i64 }
+  %struct.baz = type { [4 x i32] }
+  %struct.snork = type { i32, i32, [1 x %struct.spam] }
+  %struct.spam = type { %struct.baz, i32, i32 }
+  %struct.zot = type { i64, i64 }
+  %struct.wombat = type { [2 x i32] }
+  %struct.wombat.0 = type { [200 x i32] }
+  
+  @__stack_chk_guard = external global i8*
+  
+  ; Function Attrs: noredzone ssp
+  define hidden void @with_noredzone_80bytes() #0 {
+  bb:
+    %StackGuardSlot = alloca i8*, align 8
+    %0 = call i8* @llvm.stackguard()
+    call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot)
+    %tmp = alloca %struct.widget, align 16
+    %tmp1 = alloca %struct.wombat.0*, align 8
+    %tmp2 = alloca %struct.wombat.0*, align 8
+    %tmp3 = alloca %struct.wombat.0*, align 8
+    %tmp4 = alloca %struct.wombat.0*, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp3, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp4, align 8
+    ret void
+  }
+
+  define hidden void @with_redzone_480bytes() #2 {
+  bb:
+    %StackGuardSlot = alloca i8*, align 8
+    %0 = call i8* @llvm.stackguard()
+    call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot)
+    %tmp = alloca %struct.widget, align 16
+    %tmp1 = alloca %struct.wombat.0*, align 8
+    %tmp2 = alloca %struct.wombat.0*, align 8
+    %tmp3 = alloca %struct.wombat.0*, align 8
+    %tmp4 = alloca %struct.wombat.0*, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp3, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp4, align 8
+    ret void
+  }
+
+  define hidden void @with_noredzone_no_mem_between() #0 {
+  bb:
+    %StackGuardSlot = alloca i8*, align 8
+    %0 = call i8* @llvm.stackguard()
+    call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot)
+    %tmp = alloca %struct.widget, align 16
+    %tmp1 = alloca %struct.wombat.0*, align 8
+    %tmp2 = alloca %struct.wombat.0*, align 8
+    %tmp3 = alloca %struct.wombat.0*, align 8
+    %tmp4 = alloca %struct.wombat.0*, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp3, align 8
+    store %struct.wombat.0* null, %struct.wombat.0** %tmp4, align 8
+    ret void
+  }
+
+  ; Function Attrs: nofree nosync nounwind willreturn
+  declare i8* @llvm.stackguard() #1
+  
+  ; Function Attrs: nofree nosync nounwind willreturn
+  declare void @llvm.stackprotector(i8*, i8**) #1
+  
+  attributes #0 = { noredzone ssp "frame-pointer"="non-leaf" }
+  attributes #1 = { nofree nosync nounwind willreturn }
+  attributes #2 = { ssp "frame-pointer"="non-leaf" }
+...
+# Check that we don't try to combine the SUB with the STP using pre-index addressing
+# if the function does not have redzone enabled.
+# CHECK-LABEL: name: with_noredzone_80bytes
+# CHECK-NOT: STPXpre $xzr, $xzr
+---
+name:            with_noredzone_80bytes
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+registers:       []
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       512
+  offsetAdjustment: 0
+  maxAlignment:    16
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  '%stack.0.StackGuardSlot'
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  localFrameSize:  480
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: StackGuardSlot, type: default, offset: -40, size: 8, 
+      alignment: 8, stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -8, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 1, name: tmp, type: default, offset: -480, size: 440, alignment: 16, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -448, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 2, name: tmp1, type: default, offset: -488, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -456, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 3, name: tmp2, type: default, offset: -496, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -464, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 4, name: tmp3, type: default, offset: -504, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -472, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 5, name: tmp4, type: default, offset: -512, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -480, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 6, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 7, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 8, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x27', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 9, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x28', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  hasRedZone:      false
+body:             |
+  bb.0.bb:
+    successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+    liveins: $x27, $x28, $lr
+    early-clobber $sp = frame-setup STPXpre killed $x28, killed $x27, $sp, -4 :: (store 8 into %stack.9), (store 8 into %stack.8)
+    frame-setup STPXi killed $fp, killed $lr, $sp, 2 :: (store 8 into %stack.7), (store 8 into %stack.6)
+    $fp = frame-setup ADDXri $sp, 16, 0
+    $sp = frame-setup SUBXri $sp, 80, 0
+    frame-setup CFI_INSTRUCTION def_cfa $w29, 16
+    frame-setup CFI_INSTRUCTION offset $w30, -8
+    frame-setup CFI_INSTRUCTION offset $w29, -16
+    frame-setup CFI_INSTRUCTION offset $w27, -24
+    frame-setup CFI_INSTRUCTION offset $w28, -32
+    $x8 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    $x8 = LDRXui killed $x8, target-flags(aarch64-pageoff, aarch64-got, aarch64-nc) @__stack_chk_guard
+    $x8 = LDRXui killed $x8, 0 :: (dereferenceable invariant load 8 from @__stack_chk_guard)
+    STURXi killed renamable $x8, $fp, -24 :: (volatile store 8 into %stack.0.StackGuardSlot)
+    STRXui $xzr, $sp, 1 :: (store 8 into %ir.tmp3)
+    STRXui $xzr, $sp, 0 :: (store 8 into %ir.tmp4)
+    renamable $x8 = LDURXi $fp, -24 :: (volatile load 8 from %stack.0.StackGuardSlot)
+    $x9 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, target-flags(aarch64-pageoff, aarch64-got, aarch64-nc) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, 0 :: (dereferenceable invariant load 8 from @__stack_chk_guard)
+    $xzr = SUBSXrs killed renamable $x9, killed renamable $x8, 0, implicit-def $nzcv, implicit-def $nzcv
+    Bcc 1, %bb.2, implicit $nzcv
+  
+  bb.1.bb:
+    $sp = frame-destroy ADDXri $sp, 480, 0
+    $fp, $lr = frame-destroy LDPXi $sp, 2 :: (load 8 from %stack.7), (load 8 from %stack.6)
+    early-clobber $sp, $x28, $x27 = frame-destroy LDPXpost $sp, 4 :: (load 8 from %stack.9), (load 8 from %stack.8)
+    RET undef $lr
+  
+  bb.2.bb:
+    BL &__stack_chk_fail, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+
+...
+# Check we don't try to fold a 480 byte offset, even if we have a 128 byte redzone.
+# CHECK-LABEL: name: with_redzone_480bytes
+# CHECK-NOT: STPXpre $xzr, $xzr
+---
+name:            with_redzone_480bytes
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+registers:       []
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       512
+  offsetAdjustment: 0
+  maxAlignment:    16
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  '%stack.0.StackGuardSlot'
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  localFrameSize:  480
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: StackGuardSlot, type: default, offset: -40, size: 8, 
+      alignment: 8, stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -8, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 1, name: tmp, type: default, offset: -480, size: 440, alignment: 16, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -448, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 2, name: tmp1, type: default, offset: -488, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -456, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 3, name: tmp2, type: default, offset: -496, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -464, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 4, name: tmp3, type: default, offset: -504, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -472, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 5, name: tmp4, type: default, offset: -512, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -480, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 6, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 7, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 8, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x27', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 9, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x28', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+body:             |
+  bb.0.bb:
+    successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+    liveins: $x27, $x28, $lr
+    early-clobber $sp = frame-setup STPXpre killed $x28, killed $x27, $sp, -4 :: (store 8 into %stack.9), (store 8 into %stack.8)
+    frame-setup STPXi killed $fp, killed $lr, $sp, 2 :: (store 8 into %stack.7), (store 8 into %stack.6)
+    $fp = frame-setup ADDXri $sp, 16, 0
+    $sp = frame-setup SUBXri $sp, 480, 0
+    frame-setup CFI_INSTRUCTION def_cfa $w29, 16
+    frame-setup CFI_INSTRUCTION offset $w30, -8
+    frame-setup CFI_INSTRUCTION offset $w29, -16
+    frame-setup CFI_INSTRUCTION offset $w27, -24
+    frame-setup CFI_INSTRUCTION offset $w28, -32
+    $x8 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    $x8 = LDRXui killed $x8, target-flags(aarch64-pageoff, aarch64-got, aarch64-nc) @__stack_chk_guard
+    $x8 = LDRXui killed $x8, 0 :: (dereferenceable invariant load 8 from @__stack_chk_guard)
+    STURXi killed renamable $x8, $fp, -24 :: (volatile store 8 into %stack.0.StackGuardSlot)
+    STRXui $xzr, $sp, 1 :: (store 8 into %ir.tmp3)
+    STRXui $xzr, $sp, 0 :: (store 8 into %ir.tmp4)
+    renamable $x8 = LDURXi $fp, -24 :: (volatile load 8 from %stack.0.StackGuardSlot)
+    $x9 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, target-flags(aarch64-pageoff, aarch64-got, aarch64-nc) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, 0 :: (dereferenceable invariant load 8 from @__stack_chk_guard)
+    $xzr = SUBSXrs killed renamable $x9, killed renamable $x8, 0, implicit-def $nzcv, implicit-def $nzcv
+    Bcc 1, %bb.2, implicit $nzcv
+  
+  bb.1.bb:
+    $sp = frame-destroy ADDXri $sp, 480, 0
+    $fp, $lr = frame-destroy LDPXi $sp, 2 :: (load 8 from %stack.7), (load 8 from %stack.6)
+    early-clobber $sp, $x28, $x27 = frame-destroy LDPXpost $sp, 4 :: (load 8 from %stack.9), (load 8 from %stack.8)
+    RET undef $lr
+  
+  bb.2.bb:
+    BL &__stack_chk_fail, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+
+...
+# Check we still do the opt if there are no mem ops between.
+# CHECK-LABEL: name: with_noredzone_no_mem_between
+# CHECK: STPXpre $xzr, $xzr
+---
+name:            with_noredzone_no_mem_between
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+registers:       []
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       512
+  offsetAdjustment: 0
+  maxAlignment:    16
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  '%stack.0.StackGuardSlot'
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  localFrameSize:  480
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: StackGuardSlot, type: default, offset: -40, size: 8, 
+      alignment: 8, stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -8, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 1, name: tmp, type: default, offset: -480, size: 440, alignment: 16, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -448, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 2, name: tmp1, type: default, offset: -488, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -456, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 3, name: tmp2, type: default, offset: -496, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -464, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 4, name: tmp3, type: default, offset: -504, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -472, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 5, name: tmp4, type: default, offset: -512, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -480, debug-info-variable: '', debug-info-expression: '', 
+      debug-info-location: '' }
+  - { id: 6, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 7, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 8, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x27', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 9, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '$x28', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  hasRedZone:      false
+body:             |
+  bb.0.bb:
+    successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+    liveins: $x27, $x28, $lr
+    early-clobber $sp = frame-setup STPXpre killed $x28, killed $x27, $sp, -4 :: (store 8 into %stack.9), (store 8 into %stack.8)
+    frame-setup STPXi killed $fp, killed $lr, $sp, 2 :: (store 8 into %stack.7), (store 8 into %stack.6)
+    $fp = frame-setup ADDXri $sp, 16, 0
+    $sp = frame-setup SUBXri $sp, 480, 0
+    frame-setup CFI_INSTRUCTION def_cfa $w29, 16
+    frame-setup CFI_INSTRUCTION offset $w30, -8
+    frame-setup CFI_INSTRUCTION offset $w29, -16
+    frame-setup CFI_INSTRUCTION offset $w27, -24
+    frame-setup CFI_INSTRUCTION offset $w28, -32
+    $x8 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    STRXui $xzr, $sp, 1 :: (store 8 into %ir.tmp3)
+    STRXui $xzr, $sp, 0 :: (store 8 into %ir.tmp4)
+    renamable $x8 = LDURXi $fp, -24 :: (volatile load 8 from %stack.0.StackGuardSlot)
+    $x9 = ADRP target-flags(aarch64-page, aarch64-got) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, target-flags(aarch64-pageoff, aarch64-got, aarch64-nc) @__stack_chk_guard
+    $x9 = LDRXui killed $x9, 0 :: (dereferenceable invariant load 8 from @__stack_chk_guard)
+    $xzr = SUBSXrs killed renamable $x9, killed renamable $x8, 0, implicit-def $nzcv, implicit-def $nzcv
+    Bcc 1, %bb.2, implicit $nzcv
+  
+  bb.1.bb:
+    $sp = frame-destroy ADDXri $sp, 480, 0
+    $fp, $lr = frame-destroy LDPXi $sp, 2 :: (load 8 from %stack.7), (load 8 from %stack.6)
+    early-clobber $sp, $x28, $x27 = frame-destroy LDPXpost $sp, 4 :: (load 8 from %stack.9), (load 8 from %stack.8)
+    RET undef $lr
+  
+  bb.2.bb:
+    BL &__stack_chk_fail, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+
+...


        


More information about the llvm-commits mailing list