diff options
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 4 | ||||
-rw-r--r-- | test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll | 55 |
2 files changed, 57 insertions, 2 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 624d65b..7f9d082 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1744,7 +1744,7 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF, // Calculate the new stack slot for the return address. int SlotSize = Is64Bit ? 8 : 4; int NewReturnAddrFI = - MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize, true,false); + MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize, false, false); EVT VT = Is64Bit ? MVT::i64 : MVT::i32; SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT); Chain = DAG.getStore(Chain, dl, RetAddrFrIdx, NewRetAddrFrIdx, @@ -2377,7 +2377,7 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { // Set up a frame object for the return address. uint64_t SlotSize = TD->getPointerSize(); ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, - true, false); + false, false); FuncInfo->setRAIndex(ReturnAddrIndex); } diff --git a/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll new file mode 100644 index 0000000..eb21dc2 --- /dev/null +++ b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll @@ -0,0 +1,55 @@ +; RUN: llc -mtriple=i386-apple-darwin -tailcallopt < %s | FileCheck %s +; Check that lowered argumens do not overwrite the return address before it is moved. +; Bug 6225 +; +; If a call is a fastcc tail call and tail call optimization is enabled, the +; caller frame is replaced by the callee frame. This can require that arguments are +; placed on the former return address stack slot. Special care needs to be taken +; taken that the return address is moved / or stored in a register before +; lowering of arguments potentially overwrites the value. +; +; Move return address (76(%esp)) to a temporary register (%ebp) +; CHECK: movl 76(%esp), %ebp +; Overwrite return addresss +; CHECK: movl %ecx, 76(%esp) +; Move return address from temporary register (%ebp) to new stack location (60(%esp)) +; CHECK: movl %ebp, 60(%esp) + +%tupl_p = type [9 x i32]* + +declare fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind +declare fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind + +define fastcc void @l186(%tupl_p %r1) noreturn nounwind { +entry: + %ptr1 = getelementptr %tupl_p %r1, i32 0, i32 0 + %r2 = load i32* %ptr1 + %ptr3 = getelementptr %tupl_p %r1, i32 0, i32 1 + %r3 = load i32* %ptr3 + %ptr5 = getelementptr %tupl_p %r1, i32 0, i32 2 + %r4 = load i32* %ptr5 + %ptr7 = getelementptr %tupl_p %r1, i32 0, i32 3 + %r5 = load i32* %ptr7 + %ptr9 = getelementptr %tupl_p %r1, i32 0, i32 4 + %r6 = load i32* %ptr9 + %ptr11 = getelementptr %tupl_p %r1, i32 0, i32 5 + %r7 = load i32* %ptr11 + %ptr13 = getelementptr %tupl_p %r1, i32 0, i32 6 + %r8 = load i32* %ptr13 + %ptr15 = getelementptr %tupl_p %r1, i32 0, i32 7 + %r9 = load i32* %ptr15 + %ptr17 = getelementptr %tupl_p %r1, i32 0, i32 8 + %r10 = load i32* %ptr17 + %cond = icmp eq i32 %r10, 3 + br i1 %cond, label %true, label %false + +true: + tail call fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind + ret void + +false: + tail call fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind + ret void +} + + |