On x86-32, structure return via sret lets the callee pop the hidden
pointer argument off the stack, which the caller then re-pushes.
However if the calling convention is fastcc, then a register is used
instead, and the caller should not adjust the stack. This is
implemented with a check of IsTailCallConvention
X86TargetLowering::LowerCall but is now checked properly in
X86FastISel::DoSelectCall.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155745
91177308-0d34-0410-b5e6-
96231b3b80d8
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
unsigned NumBytesCallee = 0;
if (!Subtarget->is64Bit() && !Subtarget->isTargetWindows() &&
+ !(CS.getCallingConv() == CallingConv::Fast ||
+ CS.getCallingConv() == CallingConv::GHC) &&
CS.paramHasAttr(1, Attribute::StructRet))
NumBytesCallee = 4;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp))
; CHECK: addl $40
}
declare void @test3sret(%struct.a* sret)
+
+; Check that fast-isel sret works with fastcc (and does not callee-pop)
+define void @test4() nounwind ssp {
+entry:
+ %tmp = alloca %struct.a, align 8
+ call fastcc void @test4fastccsret(%struct.a* sret %tmp)
+ ret void
+; CHECK: test4:
+; CHECK: subl $44
+; CHECK: leal 16(%esp)
+; CHECK: calll _test4fastccsret
+; CHECK addl $40
+}
+declare fastcc void @test4fastccsret(%struct.a* sret)