Skip to content

Commit 80f1564

Browse files
committed
Fix calculation for alignment over 128 bytes
1 parent bfc07e5 commit 80f1564

File tree

4 files changed

+45
-52
lines changed

4 files changed

+45
-52
lines changed

llvm/lib/Target/Sparc/SparcISelLowering.cpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,22 +2770,8 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
27702770
EVT VT = Size->getValueType(0);
27712771
SDLoc dl(Op);
27722772

2773-
int64_t Bias = Subtarget->getStackPointerBias();
27742773
unsigned SPReg = SP::O6;
27752774
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
2776-
SDValue AllocatedPtr = DAG.getNode(ISD::SUB, dl, VT, SP, Size);
2777-
2778-
bool IsOveraligned = MaybeAlignment.has_value();
2779-
SDValue AlignedPtr =
2780-
IsOveraligned
2781-
? DAG.getNode(ISD::AND, dl, VT,
2782-
DAG.getNode(ISD::SUB, dl, VT,
2783-
DAG.getNode(ISD::ADD, dl, VT, AllocatedPtr,
2784-
DAG.getConstant(Bias, dl, VT)),
2785-
Alignment),
2786-
DAG.getNode(ISD::SUB, dl, VT,
2787-
DAG.getConstant(0, dl, VT), Alignment))
2788-
: AllocatedPtr;
27892775

27902776
// The resultant pointer needs to be above the register spill area
27912777
// at the bottom of the stack.
@@ -2819,17 +2805,30 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
28192805
regSpillArea = 96;
28202806
}
28212807

2822-
// If we are allocating overaligned memory then the AlignedPtr calculation
2823-
// adds the bias into SP, so we need to restore biased SP by decrementing
2824-
// AlignedPtr back here.
2825-
SDValue NewSP =
2826-
DAG.getNode(ISD::SUB, dl, VT, AlignedPtr,
2827-
DAG.getConstant(IsOveraligned ? Bias : 0, dl, VT));
2828-
Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);
2808+
int64_t Bias = Subtarget->getStackPointerBias();
2809+
2810+
// Debias and increment SP past the reserved spill area.
2811+
// We need the SP to point to the first usable region before calculating
2812+
// anything to prevent any of the pointers from becoming out of alignment when
2813+
// we rebias the SP later on.
2814+
SDValue StartOfUsableStack = DAG.getNode(
2815+
ISD::ADD, dl, VT, SP, DAG.getConstant(regSpillArea + Bias, dl, VT));
2816+
SDValue AllocatedPtr =
2817+
DAG.getNode(ISD::SUB, dl, VT, StartOfUsableStack, Size);
2818+
2819+
bool IsOveraligned = MaybeAlignment.has_value();
2820+
SDValue AlignedPtr =
2821+
IsOveraligned
2822+
? DAG.getNode(ISD::AND, dl, VT, AllocatedPtr,
2823+
DAG.getNode(ISD::SUB, dl, VT,
2824+
DAG.getConstant(0, dl, VT), Alignment))
2825+
: AllocatedPtr;
28292826

2830-
SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP,
2831-
DAG.getConstant(regSpillArea + Bias, dl, VT));
2832-
SDValue Ops[2] = { NewVal, Chain };
2827+
// Now that we are done, restore the bias and reserved spill area.
2828+
SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, AlignedPtr,
2829+
DAG.getConstant(regSpillArea + Bias, dl, VT));
2830+
Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);
2831+
SDValue Ops[2] = {AlignedPtr, Chain};
28332832
return DAG.getMergeValues(Ops, dl);
28342833
}
28352834

llvm/test/CodeGen/SPARC/2013-05-17-CallFrame.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ define void @variable_alloca_with_adj_call_stack(i32 %num) nounwind {
1212
; V8-NEXT: add %i0, 7, %i0
1313
; V8-NEXT: and %i0, -8, %i0
1414
; V8-NEXT: sub %sp, %i0, %i0
15-
; V8-NEXT: add %i0, 96, %o0
16-
; V8-NEXT: mov %i0, %sp
15+
; V8-NEXT: add %i0, -8, %sp
16+
; V8-NEXT: add %i0, 88, %o0
1717
; V8-NEXT: add %sp, -16, %sp
1818
; V8-NEXT: st %o0, [%sp+104]
1919
; V8-NEXT: st %o0, [%sp+100]

llvm/test/CodeGen/SPARC/alloca-align.ll

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,24 @@ define void @variable_alloca_with_overalignment(i32 %num) nounwind {
66
; CHECK32-LABEL: variable_alloca_with_overalignment:
77
; CHECK32: ! %bb.0:
88
; CHECK32-NEXT: save %sp, -96, %sp
9-
; CHECK32-NEXT: add %sp, -72, %i1
10-
; CHECK32-NEXT: and %i1, -64, %i1
11-
; CHECK32-NEXT: add %i1, 96, %o0
12-
; CHECK32-NEXT: mov %i1, %sp
9+
; CHECK32-NEXT: add %sp, 80, %i1
10+
; CHECK32-NEXT: and %i1, -64, %o0
11+
; CHECK32-NEXT: add %o0, -96, %sp
1312
; CHECK32-NEXT: add %i0, 7, %i0
1413
; CHECK32-NEXT: and %i0, -8, %i0
1514
; CHECK32-NEXT: sub %sp, %i0, %i0
16-
; CHECK32-NEXT: add %i0, 96, %o1
15+
; CHECK32-NEXT: add %i0, -8, %sp
1716
; CHECK32-NEXT: call foo
18-
; CHECK32-NEXT: mov %i0, %sp
17+
; CHECK32-NEXT: add %i0, 88, %o1
1918
; CHECK32-NEXT: ret
2019
; CHECK32-NEXT: restore
2120
;
2221
; CHECK64-LABEL: variable_alloca_with_overalignment:
2322
; CHECK64: ! %bb.0:
2423
; CHECK64-NEXT: save %sp, -128, %sp
25-
; CHECK64-NEXT: add %sp, 1967, %i1
26-
; CHECK64-NEXT: and %i1, -64, %i1
27-
; CHECK64-NEXT: add %i1, -2047, %sp
28-
; CHECK64-NEXT: add %i1, 128, %o0
24+
; CHECK64-NEXT: add %sp, 2159, %i1
25+
; CHECK64-NEXT: and %i1, -64, %o0
26+
; CHECK64-NEXT: add %o0, -2175, %sp
2927
; CHECK64-NEXT: srl %i0, 0, %i0
3028
; CHECK64-NEXT: add %i0, 15, %i0
3129
; CHECK64-NEXT: sethi 4194303, %i1
@@ -57,10 +55,9 @@ define void @variable_alloca_with_overalignment_2(i32 %num) nounwind {
5755
; CHECK32-NEXT: add %i0, 7, %i0
5856
; CHECK32-NEXT: and %i0, -8, %i0
5957
; CHECK32-NEXT: sub %sp, %i0, %i0
60-
; CHECK32-NEXT: add %i0, -64, %i0
61-
; CHECK32-NEXT: and %i0, -64, %i0
62-
; CHECK32-NEXT: add %i0, 96, %o1
63-
; CHECK32-NEXT: mov %i0, %sp
58+
; CHECK32-NEXT: add %i0, 88, %i0
59+
; CHECK32-NEXT: and %i0, -64, %o1
60+
; CHECK32-NEXT: add %o1, -96, %sp
6461
; CHECK32-NEXT: call foo
6562
; CHECK32-NEXT: mov %g0, %o0
6663
; CHECK32-NEXT: ret
@@ -79,10 +76,9 @@ define void @variable_alloca_with_overalignment_2(i32 %num) nounwind {
7976
; CHECK64-NEXT: or %i2, %i1, %i1
8077
; CHECK64-NEXT: and %i0, %i1, %i0
8178
; CHECK64-NEXT: sub %sp, %i0, %i0
82-
; CHECK64-NEXT: add %i0, 1983, %i0
83-
; CHECK64-NEXT: and %i0, -64, %i0
84-
; CHECK64-NEXT: add %i0, -2047, %sp
85-
; CHECK64-NEXT: add %i0, 128, %o1
79+
; CHECK64-NEXT: add %i0, 2175, %i0
80+
; CHECK64-NEXT: and %i0, -64, %o1
81+
; CHECK64-NEXT: add %o1, -2175, %sp
8682
; CHECK64-NEXT: add %sp, -48, %sp
8783
; CHECK64-NEXT: call foo
8884
; CHECK64-NEXT: mov %g0, %o0

llvm/test/CodeGen/SPARC/stack-align.ll

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,19 @@ define void @stack_realign(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %
1313
; CHECK32: ! %bb.0: ! %entry
1414
; CHECK32-NEXT: save %sp, -96, %sp
1515
; CHECK32-NEXT: ld [%fp+92], %o0
16-
; CHECK32-NEXT: add %sp, -72, %i0
17-
; CHECK32-NEXT: and %i0, -64, %i0
18-
; CHECK32-NEXT: add %i0, 96, %o1
16+
; CHECK32-NEXT: add %sp, 80, %i0
17+
; CHECK32-NEXT: and %i0, -64, %o1
1918
; CHECK32-NEXT: call stack_realign_helper
20-
; CHECK32-NEXT: mov %i0, %sp
19+
; CHECK32-NEXT: add %o1, -96, %sp
2120
; CHECK32-NEXT: ret
2221
; CHECK32-NEXT: restore
2322
;
2423
; CHECK64-LABEL: stack_realign:
2524
; CHECK64: ! %bb.0: ! %entry
2625
; CHECK64-NEXT: save %sp, -128, %sp
27-
; CHECK64-NEXT: add %sp, 1967, %i0
28-
; CHECK64-NEXT: and %i0, -64, %i0
29-
; CHECK64-NEXT: add %i0, -2047, %sp
30-
; CHECK64-NEXT: add %i0, 128, %o1
26+
; CHECK64-NEXT: add %sp, 2159, %i0
27+
; CHECK64-NEXT: and %i0, -64, %o1
28+
; CHECK64-NEXT: add %o1, -2175, %sp
3129
; CHECK64-NEXT: add %sp, -48, %sp
3230
; CHECK64-NEXT: call stack_realign_helper
3331
; CHECK64-NEXT: ld [%fp+2227], %o0

0 commit comments

Comments
 (0)