Skip to content

Commit 9c5957b

Browse files
committed
[Xtensa] Fix VASTART lowering.
1 parent 5df1c75 commit 9c5957b

File tree

2 files changed

+55
-38
lines changed

2 files changed

+55
-38
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,18 +1908,20 @@ SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
19081908
// next variable argument
19091909

19101910
SDValue VAIndex;
1911+
SDValue OverflowPtrAdvance;
19111912
SDValue StackOffsetFI =
19121913
DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);
19131914
unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;
19141915

1915-
// If first variable argument passed in registers (maximum words in registers
1916-
// is 6) then set va_ndx to the position of this argument in registers area
1917-
// stored in memory (va_reg pointer). Otherwise va_ndx should point to the
1918-
// position of the first variable argument on stack (va_stk pointer).
19191916
if (ArgWords < 6) {
19201917
VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);
1918+
OverflowPtrAdvance = DAG.getConstant(32, DL, PtrVT);
19211919
} else {
1922-
VAIndex = DAG.getConstant(32, DL, MVT::i32);
1920+
OverflowPtrAdvance = DAG.getNode(ISD::AND, DL, PtrVT, StackOffsetFI,
1921+
DAG.getConstant(0xf, DL, PtrVT));
1922+
OverflowPtrAdvance = DAG.getNode(ISD::ADD, DL, PtrVT, OverflowPtrAdvance,
1923+
DAG.getConstant(32, DL, PtrVT));
1924+
VAIndex = OverflowPtrAdvance;
19231925
}
19241926

19251927
SDValue FrameIndex =
@@ -1928,8 +1930,8 @@ SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
19281930
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
19291931

19301932
// Store pointer to arguments given on stack (va_stk)
1931-
SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,
1932-
DAG.getConstant(32, DL, PtrVT));
1933+
SDValue StackPtr =
1934+
DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI, OverflowPtrAdvance);
19331935

19341936
SDValue StoreStackPtr =
19351937
DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));
@@ -1939,7 +1941,9 @@ SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
19391941
DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
19401942

19411943
// Store pointer to arguments given on registers (va_reg)
1942-
SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,
1944+
SDValue FRAdvance = DAG.getConstant(ArgWords * 4, DL, PtrVT);
1945+
SDValue FRDecr = DAG.getNode(ISD::SUB, DL, PtrVT, FrameIndex, FRAdvance);
1946+
SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FRDecr, NextPtr,
19431947
MachinePointerInfo(SV, NextOffset));
19441948
NextOffset += FrameOffset;
19451949
NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));

llvm/test/CodeGen/Xtensa/vararg.ll

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,12 @@ define void @vararg_fixed_1(i32 %a1, ...) nounwind {
108108
; CHECK-NEXT: s32i.n a5, a1, 12
109109
; CHECK-NEXT: s32i.n a4, a1, 8
110110
; CHECK-NEXT: s32i.n a3, a1, 4
111-
; CHECK-NEXT: addi a10, a1, 4
112-
; CHECK-NEXT: s32i.n a10, a1, 4
113111
; CHECK-NEXT: addi a8, a1, 64
114112
; CHECK-NEXT: addi a8, a8, -32
115113
; CHECK-NEXT: s32i.n a8, a1, 0
114+
; CHECK-NEXT: addi a9, a1, 4
115+
; CHECK-NEXT: addi a10, a9, -4
116+
; CHECK-NEXT: s32i.n a10, a1, 4
116117
; CHECK-NEXT: movi.n a9, 8
117118
; CHECK-NEXT: movi.n a7, 24
118119
; CHECK-NEXT: blt a7, a9, .LBB2_2
@@ -185,11 +186,12 @@ define void @vararg_fixed_4(i32 %a1, i32 %a2, i32 %a3, i32 %a4, ...) nounwind {
185186
; CHECK-NEXT: entry a1, 48
186187
; CHECK-NEXT: s32i.n a7, a1, 8
187188
; CHECK-NEXT: s32i.n a6, a1, 4
188-
; CHECK-NEXT: addi a10, a1, 4
189-
; CHECK-NEXT: s32i.n a10, a1, 4
190189
; CHECK-NEXT: addi a8, a1, 48
191190
; CHECK-NEXT: addi a8, a8, -32
192191
; CHECK-NEXT: s32i.n a8, a1, 0
192+
; CHECK-NEXT: addi a9, a1, 4
193+
; CHECK-NEXT: addi a10, a9, -16
194+
; CHECK-NEXT: s32i.n a10, a1, 4
193195
; CHECK-NEXT: movi.n a9, 20
194196
; CHECK-NEXT: movi.n a7, 24
195197
; CHECK-NEXT: blt a7, a9, .LBB3_2
@@ -261,11 +263,12 @@ define void @vararg_fixed_5(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, ...) no
261263
; CHECK: # %bb.0: # %entry
262264
; CHECK-NEXT: entry a1, 48
263265
; CHECK-NEXT: s32i.n a7, a1, 4
264-
; CHECK-NEXT: addi a9, a1, 4
265-
; CHECK-NEXT: s32i.n a9, a1, 4
266266
; CHECK-NEXT: addi a8, a1, 48
267267
; CHECK-NEXT: addi a8, a8, -32
268268
; CHECK-NEXT: s32i.n a8, a1, 0
269+
; CHECK-NEXT: addi a9, a1, 4
270+
; CHECK-NEXT: addi a9, a9, -20
271+
; CHECK-NEXT: s32i.n a9, a1, 4
269272
; CHECK-NEXT: movi.n a7, 24
270273
; CHECK-NEXT: blt a7, a7, .LBB4_2
271274
; CHECK-NEXT: # %bb.1: # %entry
@@ -338,23 +341,28 @@ define void @vararg_fixed_6(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6
338341
; CHECK-LABEL: vararg_fixed_6:
339342
; CHECK: # %bb.0: # %entry
340343
; CHECK-NEXT: entry a1, 48
341-
; CHECK-NEXT: addi a10, a1, 48
342-
; CHECK-NEXT: s32i.n a10, a1, 4
343-
; CHECK-NEXT: addi a8, a1, 48
344-
; CHECK-NEXT: addi a8, a8, -32
345-
; CHECK-NEXT: s32i.n a8, a1, 0
346-
; CHECK-NEXT: movi.n a9, 36
344+
; CHECK-NEXT: movi.n a8, 12
345+
; CHECK-NEXT: addi a9, a1, 48
346+
; CHECK-NEXT: and a10, a9, a8
347+
; CHECK-NEXT: addi a8, a10, 36
348+
; CHECK-NEXT: movi.n a11, 32
349+
; CHECK-NEXT: or a11, a10, a11
350+
; CHECK-NEXT: sub a9, a9, a11
351+
; CHECK-NEXT: s32i.n a9, a1, 0
352+
; CHECK-NEXT: addi a11, a1, 48
353+
; CHECK-NEXT: addi a11, a11, -24
354+
; CHECK-NEXT: s32i.n a11, a1, 4
347355
; CHECK-NEXT: movi.n a7, 24
348-
; CHECK-NEXT: blt a7, a9, .LBB5_2
356+
; CHECK-NEXT: blt a7, a8, .LBB5_2
349357
; CHECK-NEXT: # %bb.1: # %entry
350-
; CHECK-NEXT: mov.n a8, a10
358+
; CHECK-NEXT: mov.n a9, a11
351359
; CHECK-NEXT: .LBB5_2: # %entry
352-
; CHECK-NEXT: bge a7, a9, .LBB5_4
360+
; CHECK-NEXT: bge a7, a8, .LBB5_4
353361
; CHECK-NEXT: # %bb.3:
354-
; CHECK-NEXT: movi.n a9, 72
362+
; CHECK-NEXT: addi a8, a10, 72
355363
; CHECK-NEXT: .LBB5_4: # %entry
356-
; CHECK-NEXT: s32i.n a9, a1, 8
357-
; CHECK-NEXT: add.n a8, a9, a8
364+
; CHECK-NEXT: s32i.n a8, a1, 8
365+
; CHECK-NEXT: add.n a8, a8, a9
358366
; CHECK-NEXT: addi a8, a8, -4
359367
; CHECK-NEXT: l32i.n a8, a8, 0
360368
; CHECK-NEXT: add.n a10, a8, a2
@@ -413,23 +421,28 @@ define void @vararg_fixed_7(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6
413421
; CHECK-LABEL: vararg_fixed_7:
414422
; CHECK: # %bb.0: # %entry
415423
; CHECK-NEXT: entry a1, 48
416-
; CHECK-NEXT: addi a10, a1, 52
417-
; CHECK-NEXT: s32i.n a10, a1, 4
418-
; CHECK-NEXT: addi a8, a1, 52
419-
; CHECK-NEXT: addi a8, a8, -32
420-
; CHECK-NEXT: s32i.n a8, a1, 0
421-
; CHECK-NEXT: movi.n a9, 36
424+
; CHECK-NEXT: movi.n a8, 12
425+
; CHECK-NEXT: addi a9, a1, 52
426+
; CHECK-NEXT: and a10, a9, a8
427+
; CHECK-NEXT: addi a8, a10, 36
428+
; CHECK-NEXT: movi.n a11, 32
429+
; CHECK-NEXT: or a11, a10, a11
430+
; CHECK-NEXT: sub a9, a9, a11
431+
; CHECK-NEXT: s32i.n a9, a1, 0
432+
; CHECK-NEXT: addi a11, a1, 52
433+
; CHECK-NEXT: addi a11, a11, -24
434+
; CHECK-NEXT: s32i.n a11, a1, 4
422435
; CHECK-NEXT: movi.n a7, 24
423-
; CHECK-NEXT: blt a7, a9, .LBB6_2
436+
; CHECK-NEXT: blt a7, a8, .LBB6_2
424437
; CHECK-NEXT: # %bb.1: # %entry
425-
; CHECK-NEXT: mov.n a8, a10
438+
; CHECK-NEXT: mov.n a9, a11
426439
; CHECK-NEXT: .LBB6_2: # %entry
427-
; CHECK-NEXT: bge a7, a9, .LBB6_4
440+
; CHECK-NEXT: bge a7, a8, .LBB6_4
428441
; CHECK-NEXT: # %bb.3:
429-
; CHECK-NEXT: movi.n a9, 72
442+
; CHECK-NEXT: addi a8, a10, 72
430443
; CHECK-NEXT: .LBB6_4: # %entry
431-
; CHECK-NEXT: s32i.n a9, a1, 8
432-
; CHECK-NEXT: add.n a8, a9, a8
444+
; CHECK-NEXT: s32i.n a8, a1, 8
445+
; CHECK-NEXT: add.n a8, a8, a9
433446
; CHECK-NEXT: addi a8, a8, -4
434447
; CHECK-NEXT: l32i.n a8, a8, 0
435448
; CHECK-NEXT: add.n a10, a8, a2

0 commit comments

Comments
 (0)