diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -2012,8 +2012,9 @@ // right thing for the emergency spill slot. bool UseFP = false; if (AFI->hasStackFrame() && !isSVE) { - // We shouldn't prefer using the FP when there is an SVE area - // in between the FP and the non-SVE locals/spills. + // We shouldn't prefer using the FP to access fixed-sized stack objects when + // there are scalable (SVE) objects in between the FP and the fixed-sized + // objects. PreferFP &= !SVEStackSize; // Note: Keeping the following as multiple 'if' statements rather than @@ -2034,7 +2035,7 @@ // offsets is smaller than for positive ones. If an offset is available // via the FP and the SP, use whichever is closest. bool FPOffsetFits = !ForSimm || FPOffset >= -256; - PreferFP |= Offset > -FPOffset; + PreferFP |= Offset > -FPOffset && !SVEStackSize; if (MFI.hasVarSizedObjects()) { // If we have variable sized objects, we can use either FP or BP, as the diff --git a/llvm/test/CodeGen/AArch64/framelayout-sve-fixed-width-access.mir b/llvm/test/CodeGen/AArch64/framelayout-sve-fixed-width-access.mir --- a/llvm/test/CodeGen/AArch64/framelayout-sve-fixed-width-access.mir +++ b/llvm/test/CodeGen/AArch64/framelayout-sve-fixed-width-access.mir @@ -10,9 +10,7 @@ ; CHECK-NEXT: addvl sp, sp, #-32 ; CHECK-NEXT: addvl sp, sp, #-28 ; CHECK-NEXT: sub sp, sp, #2064 - ; CHECK-NEXT: addvl x8, x29, #-32 - ; CHECK-NEXT: addvl x8, x8, #-28 - ; CHECK-NEXT: ldur x8, [x8, #-16] + ; CHECK-NEXT: ldr x8, [sp, #2048] ; CHECK-NEXT: addvl sp, sp, #31 ; CHECK-NEXT: addvl sp, sp, #29 ; CHECK-NEXT: add sp, sp, #2064 diff --git a/llvm/test/CodeGen/AArch64/stack-guard-sve.ll b/llvm/test/CodeGen/AArch64/stack-guard-sve.ll --- a/llvm/test/CodeGen/AArch64/stack-guard-sve.ll +++ b/llvm/test/CodeGen/AArch64/stack-guard-sve.ll @@ -152,15 +152,15 @@ ; CHECK: sub sp, sp, #16, lsl #12 ; CHECK: sub sp, sp, #16 -; Stack guard is placed below the SVE stack area +; Stack guard is placed below the SVE stack area (and above all fixed-width objects) +; CHECK-DAG: add [[STACK_GUARD_SPILL_PART_LOC:x[0-9]+]], sp, #8, lsl #12 +; CHECK-DAG: add [[STACK_GUARD_SPILL_PART_LOC]], [[STACK_GUARD_SPILL_PART_LOC]], #16 ; CHECK-DAG: ldr [[STACK_GUARD:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard] -; CHECK-DAG: addvl [[STACK_GUARD_POS:x[0-9]+]], x29, #-2 -; CHECK-DAG: stur [[STACK_GUARD]], [[[STACK_GUARD_POS]], #-8] +; CHECK-DAG: str [[STACK_GUARD]], [[[STACK_GUARD_SPILL_PART_LOC]], #32760] ; char_arr is below the stack guard -; CHECK-DAG: sub [[CHAR_ARR_1:x[0-9]+]], x29, #16 -; CHECK-DAG: addvl [[CHAR_ARR_2:x[0-9]+]], [[CHAR_ARR_1]], #-2 -; CHECK-DAG: strb wzr, [[[CHAR_ARR_2]]] +; CHECK-DAG: add [[CHAR_ARR_LOC:x[0-9]+]], sp, #16, lsl #12 +; CHECK-DAG: strb wzr, [[[CHAR_ARR_LOC]]] ; large1 is accessed via a virtual base register ; CHECK-DAG: add [[LARGE1:x[0-9]+]], sp, #8, lsl #12 @@ -208,8 +208,9 @@ ; CHECK-DAG: str [[STACK_GUARD]], [[[STACK_GUARD_POS]]] ; char_arr is below the SVE stack area -; CHECK-DAG: addvl [[CHAR_ARR:x[0-9]+]], x29, #-3 -; CHECK-DAG: sturb wzr, [[[CHAR_ARR]], #-8] +; CHECK-DAG: add [[CHAR_ARR:x[0-9]+]], sp, #15, lsl #12 // =61440 +; CHECK-DAG: add [[CHAR_ARR]], [[CHAR_ARR]], #9 +; CHECK-DAG: strb wzr, [[[CHAR_ARR]], #4095] ; large1 is accessed via a virtual base register ; CHECK-DAG: add [[LARGE1:x[0-9]+]], sp, #8, lsl #12