diff --git a/llvm/lib/Target/M68k/M68kFrameLowering.cpp b/llvm/lib/Target/M68k/M68kFrameLowering.cpp index 1445bac0b92e8..3a02225058aeb 100644 --- a/llvm/lib/Target/M68k/M68kFrameLowering.cpp +++ b/llvm/lib/Target/M68k/M68kFrameLowering.cpp @@ -33,6 +33,8 @@ using namespace llvm; +#define DEBUG_TYPE "m68k-frame" + M68kFrameLowering::M68kFrameLowering(const M68kSubtarget &STI, Align Alignment) : TargetFrameLowering(StackGrowsDown, Alignment, -4), STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) { @@ -231,8 +233,8 @@ MachineBasicBlock::iterator M68kFrameLowering::eliminateCallFramePseudoInstr( unsigned Opcode = I->getOpcode(); bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode(); DebugLoc DL = I->getDebugLoc(); - uint64_t Amount = !ReserveCallFrame ? I->getOperand(0).getImm() : 0; - uint64_t InternalAmt = (IsDestroy && Amount) ? I->getOperand(1).getImm() : 0; + uint64_t Amount = I->getOperand(0).getImm(); + uint64_t InternalAmt = (IsDestroy || Amount) ? I->getOperand(1).getImm() : 0; I = MBB.erase(I); if (!ReserveCallFrame) { diff --git a/llvm/test/CodeGen/M68k/multiple-return.ll b/llvm/test/CodeGen/M68k/multiple-return.ll index f52f422b194f5..8e97908324f05 100644 --- a/llvm/test/CodeGen/M68k/multiple-return.ll +++ b/llvm/test/CodeGen/M68k/multiple-return.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s -define { i32, i32, i32, i32 } @test() { -; CHECK-LABEL: test: +define { i32, i32, i32, i32 } @test0() { +; CHECK-LABEL: test0: ; CHECK: .cfi_startproc ; CHECK-NEXT: ; %bb.0: ; %start ; CHECK-NEXT: move.l (4,%sp), %a0 @@ -18,3 +18,73 @@ define { i32, i32, i32, i32 } @test() { start: ret { i32, i32, i32, i32 } { i32 13, i32 17, i32 19, i32 23 } } + +define void @call_test0() { +; CHECK-LABEL: call_test0: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: ; %start +; CHECK-NEXT: suba.l #20, %sp +; CHECK-NEXT: .cfi_def_cfa_offset -24 +; CHECK-NEXT: lea (4,%sp), %a0 +; CHECK-NEXT: move.l %a0, (%sp) +; CHECK-NEXT: jsr test0 +; CHECK-NEXT: adda.l #16, %sp +; CHECK-NEXT: rts +start: + %val = call { i32, i32, i32, i32 } @test0() + ret void +} + +define void @test1(ptr sret({ i32, i32, i32, i32 }) %ret_val) { +; CHECK-LABEL: test1: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: ; %start +; CHECK-NEXT: move.l (4,%sp), %d0 +; CHECK-NEXT: move.l (%sp), %a1 +; CHECK-NEXT: adda.l #4, %sp +; CHECK-NEXT: move.l %a1, (%sp) +; CHECK-NEXT: rts +start: + ret void +} + +define void @call_test1() { +; CHECK-LABEL: call_test1: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: ; %start +; CHECK-NEXT: suba.l #20, %sp +; CHECK-NEXT: .cfi_def_cfa_offset -24 +; CHECK-NEXT: lea (4,%sp), %a0 +; CHECK-NEXT: move.l %a0, (%sp) +; CHECK-NEXT: jsr test1 +; CHECK-NEXT: adda.l #16, %sp +; CHECK-NEXT: rts +start: + %ret_val = alloca { i32, i32, i32, i32 } + call void @test1(ptr %ret_val) + ret void +} + +define i32 @test2() { +; CHECK-LABEL: test2: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: ; %start +; CHECK-NEXT: moveq #13, %d0 +; CHECK-NEXT: rts +start: + ret i32 13 +} + +define void @call_test2() { +; CHECK-LABEL: call_test2: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: ; %start +; CHECK-NEXT: suba.l #4, %sp +; CHECK-NEXT: .cfi_def_cfa_offset -8 +; CHECK-NEXT: jsr test2 +; CHECK-NEXT: adda.l #4, %sp +; CHECK-NEXT: rts +start: + %0 = call i32 @test2() + ret void +}