Skip to content

Commit f2b6263

Browse files
committed
[SOL] Fix stack arguments store chain (#142)
* Fix missing arg * Refactor file * Refactor file and add tests
1 parent 12a3c8c commit f2b6263

File tree

5 files changed

+62
-43
lines changed

5 files changed

+62
-43
lines changed

llvm/lib/Target/SBF/SBFISelLowering.cpp

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,11 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
473473
SmallVector<std::pair<unsigned, SDValue>, MaxArgs> RegsToPass;
474474

475475
// Walk arg assignments
476-
bool HasStackArgs = false;
477-
unsigned e, i, ae = ArgLocs.size();
478-
for (i = 0, e = ae; i != e; ++i) {
476+
unsigned i;
477+
SmallVector<SDValue, 8> MemOpChain;
478+
SBFFunctionInfo * SBFFuncInfo = MF.getInfo<SBFFunctionInfo>();
479+
480+
for (i = 0; i < ArgLocs.size(); i++) {
479481
CCValAssign &VA = ArgLocs[i];
480482
SDValue Arg = OutVals[i];
481483

@@ -496,37 +498,13 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
496498
break;
497499
}
498500

499-
if (VA.isMemLoc()) {
500-
HasStackArgs = true;
501-
break;
502-
}
503-
504501
// Push arguments into RegsToPass vector
505502
if (VA.isRegLoc())
506503
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
507-
else
508-
llvm_unreachable("call arg pass bug");
509-
}
510-
511-
SDValue InGlue;
512-
513-
if (HasStackArgs) {
514-
SBFFunctionInfo * SBFFuncInfo = MF.getInfo<SBFFunctionInfo>();
515-
// Stack arguments have to be walked in reverse order by inserting
516-
// chained stores, this ensures their order is not changed by the scheduler
517-
// and that the push instruction sequence generated is correct, otherwise they
518-
// can be freely intermixed.
519-
for (ae = i, i = ArgLocs.size(); i != ae; --i) {
520-
unsigned Loc = i - 1;
521-
CCValAssign &VA = ArgLocs[Loc];
522-
SDValue Arg = OutVals[Loc];
504+
else if (VA.isMemLoc()) {
505+
CCValAssign &VA = ArgLocs[i];
506+
SDValue Arg = OutVals[i];
523507

524-
assert(VA.isMemLoc());
525-
526-
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
527-
SDValue DstAddr;
528-
MachinePointerInfo DstInfo;
529-
int FrameIndex;
530508
int64_t Offset = static_cast<int64_t>(VA.getLocMemOffset());
531509
uint64_t Size = VA.getLocVT().getFixedSizeInBits() / 8;
532510
if (Subtarget->getHasDynamicFrames()) {
@@ -536,14 +514,22 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
536514
Offset += Size;
537515
}
538516

539-
FrameIndex = MF.getFrameInfo().CreateFixedObject(
517+
int FrameIndex = MF.getFrameInfo().CreateFixedObject(
540518
Size, Offset, false);
541519
SBFFuncInfo->storeFrameIndexArgument(FrameIndex);
542-
DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT);
543-
DstInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex, Offset);
544-
Chain = DAG.getStore(Chain, CLI.DL, Arg, DstAddr, DstInfo);
545-
}
520+
SDValue DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT);
521+
MachinePointerInfo DstInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex, Offset);
522+
SDValue Store = DAG.getStore(Chain, CLI.DL, Arg, DstAddr, DstInfo);
523+
MemOpChain.push_back(Store);
546524

525+
} else
526+
llvm_unreachable("call arg pass bug");
527+
}
528+
529+
SDValue InGlue;
530+
531+
if (!MemOpChain.empty()) {
532+
Chain = DAG.getNode(ISD::TokenFactor, CLI.DL, MVT::Other, MemOpChain);
547533
if (!Subtarget->getHasDynamicFrames()) {
548534
// Pass the current stack frame pointer via SBF::R5, gluing the
549535
// instruction to instructions passing the first 4 arguments in
@@ -554,7 +540,6 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
554540
Chain = DAG.getCopyToReg(Chain, CLI.DL, SBF::R5, FramePtr, InGlue);
555541
InGlue = Chain.getValue(1);
556542
}
557-
558543
}
559544

560545
// Build a sequence of copy-to-reg nodes chained together with token chain and
@@ -586,7 +571,7 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
586571
for (auto &Reg : RegsToPass)
587572
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
588573

589-
if (HasStackArgs && !Subtarget->getHasDynamicFrames()) {
574+
if (!MemOpChain.empty() && !Subtarget->getHasDynamicFrames()) {
590575
Ops.push_back(DAG.getRegister(SBF::R5, MVT::i64));
591576
}
592577

llvm/test/CodeGen/SBF/many_args1.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
; Function Attrs: nounwind uwtable
44
define i32 @foo(i32 %a, i32 %b, i32 %c) #0 {
55
; CHECK-LABEL: foo:
6-
; CHECK: mov64 r4, 2
7-
; CHECK: stxdw [r10 - 4096], r4
86
; CHECK: mov64 r4, 3
97
; CHECK: stxdw [r10 - 4088], r4
8+
; CHECK: mov64 r4, 2
9+
; CHECK: stxdw [r10 - 4096], r4
1010
; CHECK: mov64 r5, r10
1111
; CHECK: mov64 r4, 1
1212
; CHECK: call bar

llvm/test/CodeGen/SBF/many_args_new_conv.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ entry:
1111
; CHECK-NOT: add64 r10
1212

1313
; Saving arguments on the stack
14-
; CHECK: stdw [r10 - 32], 55
1514
; CHECK: stdw [r10 - 40], 60
15+
; CHECK: stdw [r10 - 32], 55
1616
; CHECK: stdw [r10 - 24], 50
1717
; CHECK: stdw [r10 - 16], 4
1818
; CHECK: stdw [r10 - 8], 3
@@ -32,10 +32,10 @@ define i32 @caller_alloca(i32 %a, i32 %b, i32 %c) #0 {
3232

3333
; Saving arguments in the callee's frame
3434

35-
; Offset in the callee: frame_size - 32
36-
; CHECK: stdw [r10 - 32], 55
3735
; Offset in the callee: frame_size - 40
3836
; CHECK: stdw [r10 - 40], 60
37+
; Offset in the callee: frame_size - 32
38+
; CHECK: stdw [r10 - 32], 55
3939
; Offset in the callee: frame_size - 24
4040
; CHECK: stdw [r10 - 24], 50
4141
; Offset in the callee: frame_size - 16

llvm/test/CodeGen/SBF/many_args_value_size.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ define i64 @test_func(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) {
55
start:
66
; CHECK-LABEL: test_func:
77

8-
; CHECK: stw [r10 - 20], 300
98
; CHECK: stdw [r10 - 32], 5400
9+
; CHECK: stw [r10 - 20], 300
1010
; CHECK: stw [r10 - 12], 65516
1111
; CHECK: stw [r10 - 4], 5
1212

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; RUN: llc < %s -march=sbf -mcpu=v2 | FileCheck %s
2+
3+
4+
declare void @do_something(ptr, ptr, ptr, ptr, ptr);
5+
declare void @test(ptr dead_on_unwind noalias nocapture noundef writable align 8 dereferenceable(24) %_0, ptr noalias noundef readonly align 1 dereferenceable(32) %pool_account_key, ptr noalias nocapture noundef readonly align 8 dereferenceable(48) %token_program, ptr noalias nocapture noundef readonly align 8 dereferenceable(48) %mint, ptr noalias nocapture noundef readonly align 8 dereferenceable(48) %destination, ptr noalias nocapture noundef readonly align 8 dereferenceable(48) %authority, i8 noundef %bump_seed, i64 noundef %amount);
6+
7+
define void @func() {
8+
; CHECK-LABEL: func
9+
%185 = alloca [24 x i8], align 8
10+
%186 = alloca [48 x i8], align 8
11+
%187 = alloca [48 x i8], align 8
12+
%188 = alloca [48 x i8], align 8
13+
%189 = alloca [48 x i8], align 8
14+
15+
call void @do_something(ptr %185, ptr %186, ptr %187, ptr %188, ptr %189)
16+
%200 = load ptr, ptr %185, align 8
17+
%bump_seed = load i8, ptr %188, align 1
18+
%other = load i64, ptr %187, align 8
19+
20+
; CHECK: ldxdw r2, [r10 + 232]
21+
; CHECK: ldxb w1, [r10 + 88]
22+
; CHECK: ldxdw r3, [r10 + 136]
23+
24+
; CHECK: stxdw [r10 - 24], r3
25+
26+
; The stxw [r10 - 12] store disappears if we use chained stores.
27+
28+
; CHECK: stxw [r10 - 12], w1
29+
; CHECK: stxdw [r10 - 8], r7
30+
31+
call void @test(ptr noalias nocapture noundef nonnull align 8 dereferenceable(24) %185, ptr noalias noundef nonnull readonly align 1 dereferenceable(32) %200, ptr noalias nocapture noundef nonnull align 8 dereferenceable(48) %186, ptr noalias nocapture noundef nonnull align 8 dereferenceable(48) %187, ptr noalias nocapture noundef nonnull align 8 dereferenceable(48) %188, ptr noalias nocapture noundef nonnull align 8 dereferenceable(48) %189, i8 noundef %bump_seed, i64 noundef %other)
32+
33+
ret void
34+
}

0 commit comments

Comments
 (0)