[llvm] 23d209f - [SPARC] Allow overaligned `alloca`s (#107223)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 3 07:53:06 PST 2024
Author: Koakuma
Date: 2024-11-03T22:53:03+07:00
New Revision: 23d209f350f4e51b2a42636ce45d10c6e208252d
URL: https://github.com/llvm/llvm-project/commit/23d209f350f4e51b2a42636ce45d10c6e208252d
DIFF: https://github.com/llvm/llvm-project/commit/23d209f350f4e51b2a42636ce45d10c6e208252d.diff
LOG: [SPARC] Allow overaligned `alloca`s (#107223)
SPARC ABI doesn't use stack realignment, so let LLVM know about it in
`SparcFrameLowering`. This has the side effect of making all overaligned
allocations go through `LowerDYNAMIC_STACKALLOC`, so implement the
missing logic there too for overaligned allocations.
This makes the SPARC backend not crash on overaligned `alloca`s and fix
https://github.com/llvm/llvm-project/issues/89569.
Added:
llvm/test/CodeGen/SPARC/alloca-align.ll
Modified:
compiler-rt/test/asan/TestCases/alloca_vla_interact.cpp
llvm/lib/Target/Sparc/SparcFrameLowering.cpp
llvm/lib/Target/Sparc/SparcISelLowering.cpp
llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
llvm/lib/Target/Sparc/SparcRegisterInfo.h
llvm/test/CodeGen/Generic/ForceStackAlign.ll
llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll
llvm/test/CodeGen/SPARC/fp128.ll
llvm/test/CodeGen/SPARC/stack-align.ll
Removed:
llvm/test/CodeGen/SPARC/fail-alloca-align.ll
################################################################################
diff --git a/compiler-rt/test/asan/TestCases/alloca_vla_interact.cpp b/compiler-rt/test/asan/TestCases/alloca_vla_interact.cpp
index 96ac4c7db291a0..b98bb726dcebc3 100644
--- a/compiler-rt/test/asan/TestCases/alloca_vla_interact.cpp
+++ b/compiler-rt/test/asan/TestCases/alloca_vla_interact.cpp
@@ -3,6 +3,9 @@
//
// REQUIRES: stable-runtime
+// See https://github.com/llvm/llvm-project/issues/110956
+// XFAIL: target=sparc{{.*}}
+
// This testcase checks correct interaction between VLAs and allocas.
#include <assert.h>
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
index fa38c6cbb6ebbf..5da45e4a7ec746 100644
--- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -35,7 +35,8 @@ DisableLeafProc("disable-sparc-leaf-proc",
SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
ST.is64Bit() ? Align(16) : Align(8), 0,
- ST.is64Bit() ? Align(16) : Align(8)) {}
+ ST.is64Bit() ? Align(16) : Align(8),
+ /*StackRealignable=*/false) {}
void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF,
MachineBasicBlock &MBB,
@@ -97,12 +98,6 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
// Debug location must be unknown since the first debug location is used
// to determine the end of the prologue.
DebugLoc dl;
- bool NeedsStackRealignment = RegInfo.shouldRealignStack(MF);
-
- if (NeedsStackRealignment && !RegInfo.canRealignStack(MF))
- report_fatal_error("Function \"" + Twine(MF.getName()) + "\" required "
- "stack re-alignment, but LLVM couldn't handle it "
- "(probably because it has a dynamic alloca).");
// Get the number of bytes to allocate from the FrameInfo
int NumBytes = (int) MFI.getStackSize();
@@ -168,31 +163,6 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA));
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
-
- if (NeedsStackRealignment) {
- int64_t Bias = Subtarget.getStackPointerBias();
- unsigned regUnbiased;
- if (Bias) {
- // This clobbers G1 which we always know is available here.
- regUnbiased = SP::G1;
- // add %o6, BIAS, %g1
- BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), regUnbiased)
- .addReg(SP::O6).addImm(Bias);
- } else
- regUnbiased = SP::O6;
-
- // andn %regUnbiased, MaxAlign-1, %regUnbiased
- Align MaxAlign = MFI.getMaxAlign();
- BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), regUnbiased)
- .addReg(regUnbiased)
- .addImm(MaxAlign.value() - 1U);
-
- if (Bias) {
- // add %g1, -BIAS, %o6
- BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6)
- .addReg(regUnbiased).addImm(-Bias);
- }
- }
}
MachineBasicBlock::iterator SparcFrameLowering::
@@ -257,8 +227,7 @@ bool SparcFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
- RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
- MFI.isFrameAddressTaken();
+ MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken();
}
StackOffset
@@ -284,11 +253,6 @@ SparcFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
} else if (isFixed) {
// Otherwise, argument access should always use %fp.
UseFP = true;
- } else if (RegInfo->hasStackRealignment(MF)) {
- // If there is dynamic stack realignment, all local object
- // references need to be via %sp, to take account of the
- // re-alignment.
- UseFP = false;
} else {
// Finally, default to using %fp.
UseFP = true;
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index de4986ef1e89e4..9bfc0fc1c3e32d 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -2762,22 +2762,16 @@ static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
const SparcSubtarget *Subtarget) {
- SDValue Chain = Op.getOperand(0); // Legalize the chain.
- SDValue Size = Op.getOperand(1); // Legalize the size.
- MaybeAlign Alignment =
- cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
- Align StackAlign = Subtarget->getFrameLowering()->getStackAlign();
+ SDValue Chain = Op.getOperand(0);
+ SDValue Size = Op.getOperand(1);
+ SDValue Alignment = Op.getOperand(2);
+ MaybeAlign MaybeAlignment =
+ cast<ConstantSDNode>(Alignment)->getMaybeAlignValue();
EVT VT = Size->getValueType(0);
SDLoc dl(Op);
- // TODO: implement over-aligned alloca. (Note: also implies
- // supporting support for overaligned function frames + dynamic
- // allocations, at all, which currently isn't supported)
- if (Alignment && *Alignment > StackAlign) {
- const MachineFunction &MF = DAG.getMachineFunction();
- report_fatal_error("Function \"" + Twine(MF.getName()) + "\": "
- "over-aligned dynamic alloca not supported.");
- }
+ unsigned SPReg = SP::O6;
+ SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
// The resultant pointer needs to be above the register spill area
// at the bottom of the stack.
@@ -2811,16 +2805,29 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
regSpillArea = 96;
}
- unsigned SPReg = SP::O6;
- SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
- SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
- Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain
-
- regSpillArea += Subtarget->getStackPointerBias();
-
- SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP,
- DAG.getConstant(regSpillArea, dl, VT));
- SDValue Ops[2] = { NewVal, Chain };
+ int64_t Bias = Subtarget->getStackPointerBias();
+
+ // Debias and increment SP past the reserved spill area.
+ // We need the SP to point to the first usable region before calculating
+ // anything to prevent any of the pointers from becoming out of alignment when
+ // we rebias the SP later on.
+ SDValue StartOfUsableStack = DAG.getNode(
+ ISD::ADD, dl, VT, SP, DAG.getConstant(regSpillArea + Bias, dl, VT));
+ SDValue AllocatedPtr =
+ DAG.getNode(ISD::SUB, dl, VT, StartOfUsableStack, Size);
+
+ bool IsOveraligned = MaybeAlignment.has_value();
+ SDValue AlignedPtr =
+ IsOveraligned
+ ? DAG.getNode(ISD::AND, dl, VT, AllocatedPtr,
+ DAG.getConstant(-MaybeAlignment->value(), dl, VT))
+ : AllocatedPtr;
+
+ // Now that we are done, restore the bias and reserved spill area.
+ SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, AlignedPtr,
+ DAG.getConstant(regSpillArea + Bias, dl, VT));
+ Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);
+ SDValue Ops[2] = {AlignedPtr, Chain};
return DAG.getMergeValues(Ops, dl);
}
diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
index 71a27f77d2c6bf..e4db27a63076d8 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
@@ -226,26 +226,3 @@ SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Register SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return SP::I6;
}
-
-// Sparc has no architectural need for stack realignment support,
-// except that LLVM unfortunately currently implements overaligned
-// stack objects by depending upon stack realignment support.
-// If that ever changes, this can probably be deleted.
-bool SparcRegisterInfo::canRealignStack(const MachineFunction &MF) const {
- if (!TargetRegisterInfo::canRealignStack(MF))
- return false;
-
- // Sparc always has a fixed frame pointer register, so don't need to
- // worry about needing to reserve it. [even if we don't have a frame
- // pointer for our frame, it still cannot be used for other things,
- // or register window traps will be SADNESS.]
-
- // If there's a reserved call frame, we can use SP to access locals.
- if (getFrameLowering(MF)->hasReservedCallFrame(MF))
- return true;
-
- // Otherwise, we'd need a base pointer, but those aren't implemented
- // for SPARC at the moment.
-
- return false;
-}
diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.h b/llvm/lib/Target/Sparc/SparcRegisterInfo.h
index 58c85f33635f2d..eae859ce1a519e 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.h
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.h
@@ -40,9 +40,6 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
RegScavenger *RS = nullptr) const override;
Register getFrameRegister(const MachineFunction &MF) const override;
-
- bool canRealignStack(const MachineFunction &MF) const override;
-
};
} // end namespace llvm
diff --git a/llvm/test/CodeGen/Generic/ForceStackAlign.ll b/llvm/test/CodeGen/Generic/ForceStackAlign.ll
index 7993b3eff65b68..811a192e752ab1 100644
--- a/llvm/test/CodeGen/Generic/ForceStackAlign.ll
+++ b/llvm/test/CodeGen/Generic/ForceStackAlign.ll
@@ -5,9 +5,6 @@
; CHECK-LABEL: @f
; CHECK-LABEL: @g
-; Stack realignment not supported.
-; XFAIL: target=sparc{{.*}}
-
; NVPTX can only select dynamic_stackalloc on sm_52+ and with ptx73+
; XFAIL: target=nvptx{{.*}}
diff --git a/llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll b/llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll
index 3f6d28385e2679..9ebedfb68102fe 100644
--- a/llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll
+++ b/llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll
@@ -5,14 +5,10 @@
; (this should ideally be doing "add 4+7; and -8", instead of
; "add 7; and -8; add 8"; see comments in LowerDYNAMIC_STACKALLOC)
-define void @variable_alloca_with_adj_call_stack(i32 %num) {
+define void @variable_alloca_with_adj_call_stack(i32 %num) nounwind {
; V8-LABEL: variable_alloca_with_adj_call_stack:
-; V8: .cfi_startproc
-; V8-NEXT: ! %bb.0: ! %entry
+; V8: ! %bb.0: ! %entry
; V8-NEXT: save %sp, -96, %sp
-; V8-NEXT: .cfi_def_cfa_register %fp
-; V8-NEXT: .cfi_window_save
-; V8-NEXT: .cfi_register %o7, %i7
; V8-NEXT: add %i0, 7, %i0
; V8-NEXT: and %i0, -8, %i0
; V8-NEXT: sub %sp, %i0, %i0
@@ -34,12 +30,8 @@ define void @variable_alloca_with_adj_call_stack(i32 %num) {
; V8-NEXT: restore
;
; SPARC64-LABEL: variable_alloca_with_adj_call_stack:
-; SPARC64: .cfi_startproc
-; SPARC64-NEXT: ! %bb.0: ! %entry
+; SPARC64: ! %bb.0: ! %entry
; SPARC64-NEXT: save %sp, -128, %sp
-; SPARC64-NEXT: .cfi_def_cfa_register %fp
-; SPARC64-NEXT: .cfi_window_save
-; SPARC64-NEXT: .cfi_register %o7, %i7
; SPARC64-NEXT: srl %i0, 0, %i0
; SPARC64-NEXT: add %i0, 15, %i0
; SPARC64-NEXT: sethi 4194303, %i1
diff --git a/llvm/test/CodeGen/SPARC/alloca-align.ll b/llvm/test/CodeGen/SPARC/alloca-align.ll
new file mode 100644
index 00000000000000..f6330f16df4737
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/alloca-align.ll
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -march=sparc < %s | FileCheck %s --check-prefixes=CHECK32
+; RUN: llc -march=sparcv9 < %s | FileCheck %s --check-prefixes=CHECK64
+
+define void @variable_alloca_with_overalignment(i32 %num) nounwind {
+; CHECK32-LABEL: variable_alloca_with_overalignment:
+; CHECK32: ! %bb.0:
+; CHECK32-NEXT: save %sp, -96, %sp
+; CHECK32-NEXT: add %sp, 80, %i1
+; CHECK32-NEXT: and %i1, -64, %o0
+; CHECK32-NEXT: add %o0, -96, %sp
+; CHECK32-NEXT: add %i0, 7, %i0
+; CHECK32-NEXT: and %i0, -8, %i0
+; CHECK32-NEXT: sub %sp, %i0, %i0
+; CHECK32-NEXT: add %i0, -8, %sp
+; CHECK32-NEXT: call foo
+; CHECK32-NEXT: add %i0, 88, %o1
+; CHECK32-NEXT: ret
+; CHECK32-NEXT: restore
+;
+; CHECK64-LABEL: variable_alloca_with_overalignment:
+; CHECK64: ! %bb.0:
+; CHECK64-NEXT: save %sp, -128, %sp
+; CHECK64-NEXT: add %sp, 2159, %i1
+; CHECK64-NEXT: and %i1, -64, %o0
+; CHECK64-NEXT: add %o0, -2175, %sp
+; CHECK64-NEXT: srl %i0, 0, %i0
+; CHECK64-NEXT: add %i0, 15, %i0
+; CHECK64-NEXT: sethi 4194303, %i1
+; CHECK64-NEXT: or %i1, 1008, %i1
+; CHECK64-NEXT: sethi 0, %i2
+; CHECK64-NEXT: or %i2, 1, %i2
+; CHECK64-NEXT: sllx %i2, 32, %i2
+; CHECK64-NEXT: or %i2, %i1, %i1
+; CHECK64-NEXT: and %i0, %i1, %i0
+; CHECK64-NEXT: sub %sp, %i0, %i0
+; CHECK64-NEXT: add %i0, 2175, %o1
+; CHECK64-NEXT: mov %i0, %sp
+; CHECK64-NEXT: call foo
+; CHECK64-NEXT: add %sp, -48, %sp
+; CHECK64-NEXT: add %sp, 48, %sp
+; CHECK64-NEXT: ret
+; CHECK64-NEXT: restore
+ %aligned = alloca i32, align 64
+ %var_size = alloca i8, i32 %num, align 4
+ call void @foo(ptr %aligned, ptr %var_size)
+ ret void
+}
+
+;; Same but with the alloca itself overaligned
+define void @variable_alloca_with_overalignment_2(i32 %num) nounwind {
+; CHECK32-LABEL: variable_alloca_with_overalignment_2:
+; CHECK32: ! %bb.0:
+; CHECK32-NEXT: save %sp, -96, %sp
+; CHECK32-NEXT: add %i0, 7, %i0
+; CHECK32-NEXT: and %i0, -8, %i0
+; CHECK32-NEXT: sub %sp, %i0, %i0
+; CHECK32-NEXT: add %i0, 88, %i0
+; CHECK32-NEXT: and %i0, -64, %o1
+; CHECK32-NEXT: add %o1, -96, %sp
+; CHECK32-NEXT: call foo
+; CHECK32-NEXT: mov %g0, %o0
+; CHECK32-NEXT: ret
+; CHECK32-NEXT: restore
+;
+; CHECK64-LABEL: variable_alloca_with_overalignment_2:
+; CHECK64: ! %bb.0:
+; CHECK64-NEXT: save %sp, -128, %sp
+; CHECK64-NEXT: srl %i0, 0, %i0
+; CHECK64-NEXT: add %i0, 15, %i0
+; CHECK64-NEXT: sethi 4194303, %i1
+; CHECK64-NEXT: or %i1, 1008, %i1
+; CHECK64-NEXT: sethi 0, %i2
+; CHECK64-NEXT: or %i2, 1, %i2
+; CHECK64-NEXT: sllx %i2, 32, %i2
+; CHECK64-NEXT: or %i2, %i1, %i1
+; CHECK64-NEXT: and %i0, %i1, %i0
+; CHECK64-NEXT: sub %sp, %i0, %i0
+; CHECK64-NEXT: add %i0, 2175, %i0
+; CHECK64-NEXT: and %i0, -64, %o1
+; CHECK64-NEXT: add %o1, -2175, %sp
+; CHECK64-NEXT: add %sp, -48, %sp
+; CHECK64-NEXT: call foo
+; CHECK64-NEXT: mov %g0, %o0
+; CHECK64-NEXT: add %sp, 48, %sp
+; CHECK64-NEXT: ret
+; CHECK64-NEXT: restore
+ %var_size = alloca i8, i32 %num, align 64
+ call void @foo(ptr null, ptr %var_size)
+ ret void
+}
+
+declare void @foo(ptr, ptr);
diff --git a/llvm/test/CodeGen/SPARC/fail-alloca-align.ll b/llvm/test/CodeGen/SPARC/fail-alloca-align.ll
deleted file mode 100644
index e2dc235389b1dc..00000000000000
--- a/llvm/test/CodeGen/SPARC/fail-alloca-align.ll
+++ /dev/null
@@ -1,23 +0,0 @@
-;; Sparc backend can't currently handle variable allocas with
-;; alignment greater than the stack alignment. This code ought to
-;; compile, but doesn't currently.
-
-;; RUN: not --crash llc -march=sparc < %s 2>&1 | FileCheck %s
-;; RUN: not --crash llc -march=sparcv9 < %s 2>&1 | FileCheck %s
-;; CHECK: ERROR: Function {{.*}} required stack re-alignment
-
-define void @variable_alloca_with_overalignment(i32 %num) {
- %aligned = alloca i32, align 64
- %var_size = alloca i8, i32 %num, align 4
- call void @foo(ptr %aligned, ptr %var_size)
- ret void
-}
-
-;; Same but with the alloca itself overaligned
-define void @variable_alloca_with_overalignment_2(i32 %num) {
- %var_size = alloca i8, i32 %num, align 64
- call void @foo(ptr null, ptr %var_size)
- ret void
-}
-
-declare void @foo(ptr, ptr);
diff --git a/llvm/test/CodeGen/SPARC/fp128.ll b/llvm/test/CodeGen/SPARC/fp128.ll
index 80f3da285e053f..3e43d3eb5da70f 100644
--- a/llvm/test/CodeGen/SPARC/fp128.ll
+++ b/llvm/test/CodeGen/SPARC/fp128.ll
@@ -54,18 +54,10 @@ entry:
; CHECK-LABEL: f128_spill_large:
; CHECK: sethi 4, %g1
-; CHECK: sethi 4, %g1
-; CHECK-NEXT: add %g1, %sp, %g1
-; CHECK-NEXT: std %f{{.+}}, [%g1]
-; CHECK: sethi 4, %g1
-; CHECK-NEXT: add %g1, %sp, %g1
-; CHECK-NEXT: std %f{{.+}}, [%g1+8]
-; CHECK: sethi 4, %g1
-; CHECK-NEXT: add %g1, %sp, %g1
-; CHECK-NEXT: ldd [%g1], %f{{.+}}
-; CHECK: sethi 4, %g1
-; CHECK-NEXT: add %g1, %sp, %g1
-; CHECK-NEXT: ldd [%g1+8], %f{{.+}}
+; CHECK: std %f{{.+}}, [%fp+-16]
+; CHECK-NEXT: std %f{{.+}}, [%fp+-8]
+; CHECK: ldd [%fp+-16], %f{{.+}}
+; CHECK-NEXT: ldd [%fp+-8], %f{{.+}}
define void @f128_spill_large(ptr noalias sret(<251 x fp128>) %scalar.result, ptr byval(<251 x fp128>) %a) {
entry:
diff --git a/llvm/test/CodeGen/SPARC/stack-align.ll b/llvm/test/CodeGen/SPARC/stack-align.ll
index 6632237f08e274..c861b2d0296f0b 100644
--- a/llvm/test/CodeGen/SPARC/stack-align.ll
+++ b/llvm/test/CodeGen/SPARC/stack-align.ll
@@ -1,24 +1,37 @@
-; RUN: llc -march=sparc < %s | FileCheck %s --check-prefixes=CHECK,CHECK32
-; RUN: llc -march=sparcv9 < %s | FileCheck %s --check-prefixes=CHECK,CHECK64
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -march=sparc < %s | FileCheck %s --check-prefixes=CHECK32
+; RUN: llc -march=sparcv9 < %s | FileCheck %s --check-prefixes=CHECK64
declare void @stack_realign_helper(i32 %a, ptr %b)
;; This is a function where we have a local variable of 64-byte
-;; alignment. We want to see that the stack is aligned (the initial
-;; andn), that the local var is accessed via stack pointer (to %o1), and that
+;; alignment. We want to see that the stack is aligned (the initial add/and),
+;; that the local var is accessed via stack pointer (to %o1), and that
;; the argument is accessed via frame pointer not stack pointer (to %o0).
-;; CHECK-LABEL: stack_realign:
-;; CHECK32: andn %sp, 63, %sp
-;; CHECK32-NEXT: ld [%fp+92], %o0
-;; CHECK64: add %sp, 2047, %g1
-;; CHECK64-NEXT: andn %g1, 63, %g1
-;; CHECK64-NEXT: add %g1, -2047, %sp
-;; CHECK64-NEXT: ld [%fp+2227], %o0
-;; CHECK-NEXT: call stack_realign_helper
-;; CHECK32-NEXT: add %sp, 128, %o1
-;; CHECK64-NEXT: add %sp, 2239, %o1
-
-define void @stack_realign(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g) {
+define void @stack_realign(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g) nounwind {
+; CHECK32-LABEL: stack_realign:
+; CHECK32: ! %bb.0: ! %entry
+; CHECK32-NEXT: save %sp, -96, %sp
+; CHECK32-NEXT: ld [%fp+92], %o0
+; CHECK32-NEXT: add %sp, 80, %i0
+; CHECK32-NEXT: and %i0, -64, %o1
+; CHECK32-NEXT: call stack_realign_helper
+; CHECK32-NEXT: add %o1, -96, %sp
+; CHECK32-NEXT: ret
+; CHECK32-NEXT: restore
+;
+; CHECK64-LABEL: stack_realign:
+; CHECK64: ! %bb.0: ! %entry
+; CHECK64-NEXT: save %sp, -128, %sp
+; CHECK64-NEXT: add %sp, 2159, %i0
+; CHECK64-NEXT: and %i0, -64, %o1
+; CHECK64-NEXT: add %o1, -2175, %sp
+; CHECK64-NEXT: add %sp, -48, %sp
+; CHECK64-NEXT: call stack_realign_helper
+; CHECK64-NEXT: ld [%fp+2227], %o0
+; CHECK64-NEXT: add %sp, 48, %sp
+; CHECK64-NEXT: ret
+; CHECK64-NEXT: restore
entry:
%aligned = alloca i32, align 64
call void @stack_realign_helper(i32 %g, ptr %aligned)
More information about the llvm-commits
mailing list