From dd1cfe21295b9c37a38b7e1f716e76237de10909 Mon Sep 17 00:00:00 2001 From: Robert Lytton Date: Thu, 1 Aug 2013 08:29:44 +0000 Subject: [PATCH] XCore target: Fix Vararg handling git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187565 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/XCore/XCoreISelLowering.cpp | 26 +++++----- test/CodeGen/XCore/2011-08-01-VarargsBug.ll | 17 ------- test/CodeGen/XCore/varargs.ll | 55 +++++++++++++++++++++ 3 files changed, 69 insertions(+), 29 deletions(-) delete mode 100644 test/CodeGen/XCore/2011-08-01-VarargsBug.ll create mode 100644 test/CodeGen/XCore/varargs.ll diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 1d75a2849e8..6fc7eef5443 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -707,24 +707,26 @@ ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const SDValue XCoreTargetLowering:: LowerVAARG(SDValue Op, SelectionDAG &DAG) const { - llvm_unreachable("unimplemented"); - // FIXME Arguments passed by reference need a extra dereference. + // Whist llvm does not support aggregate varargs we can ignore + // the possibility of the ValueType being an implicit byVal vararg. SDNode *Node = Op.getNode(); + EVT VT = Node->getValueType(0); // not an aggregate + SDValue InChain = Node->getOperand(0); + SDValue VAListPtr = Node->getOperand(1); + EVT PtrVT = VAListPtr.getValueType(); + const Value *SV = cast(Node->getOperand(2))->getValue(); SDLoc dl(Node); - const Value *V = cast(Node->getOperand(2))->getValue(); - EVT VT = Node->getValueType(0); - SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), - Node->getOperand(1), MachinePointerInfo(V), + SDValue VAList = DAG.getLoad(PtrVT, dl, InChain, + VAListPtr, MachinePointerInfo(SV), false, false, false, 0); // Increment the pointer, VAList, to the next vararg - SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, - DAG.getConstant(VT.getSizeInBits(), - getPointerTy())); + SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAList, + DAG.getIntPtrConstant(VT.getSizeInBits() / 8)); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), - MachinePointerInfo(V), false, false, 0); + InChain = DAG.getStore(VAList.getValue(1), dl, nextPtr, VAListPtr, + MachinePointerInfo(SV), false, false, 0); // Load the actual argument out of the pointer VAList - return DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), + return DAG.getLoad(VT, dl, InChain, VAList, MachinePointerInfo(), false, false, false, 0); } diff --git a/test/CodeGen/XCore/2011-08-01-VarargsBug.ll b/test/CodeGen/XCore/2011-08-01-VarargsBug.ll deleted file mode 100644 index 6445a8fa8ba..00000000000 --- a/test/CodeGen/XCore/2011-08-01-VarargsBug.ll +++ /dev/null @@ -1,17 +0,0 @@ -; RUN: llc < %s -march=xcore | FileCheck %s -define void @_Z1fz(...) { -entry: -; CHECK-LABEL: _Z1fz: -; CHECK: extsp 3 -; CHECK: stw r[[REG:[0-3]{1,1}]] -; CHECK: , sp{{\[}}[[REG]]{{\]}} -; CHECK: stw r[[REG:[0-3]{1,1}]] -; CHECK: , sp{{\[}}[[REG]]{{\]}} -; CHECK: stw r[[REG:[0-3]{1,1}]] -; CHECK: , sp{{\[}}[[REG]]{{\]}} -; CHECK: stw r[[REG:[0-3]{1,1}]] -; CHECK: , sp{{\[}}[[REG]]{{\]}} -; CHECK: ldaw sp, sp[3] -; CHECK: retsp 0 - ret void -} diff --git a/test/CodeGen/XCore/varargs.ll b/test/CodeGen/XCore/varargs.ll new file mode 100644 index 00000000000..28c293390c5 --- /dev/null +++ b/test/CodeGen/XCore/varargs.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -march=xcore | FileCheck %s + +define void @_Z1fz(...) { +entry: +; CHECK-LABEL: _Z1fz: +; CHECK: extsp 3 +; CHECK: stw r[[REG:[0-3]{1,1}]] +; CHECK: , sp{{\[}}[[REG]]{{\]}} +; CHECK: stw r[[REG:[0-3]{1,1}]] +; CHECK: , sp{{\[}}[[REG]]{{\]}} +; CHECK: stw r[[REG:[0-3]{1,1}]] +; CHECK: , sp{{\[}}[[REG]]{{\]}} +; CHECK: stw r[[REG:[0-3]{1,1}]] +; CHECK: , sp{{\[}}[[REG]]{{\]}} +; CHECK: ldaw sp, sp[3] +; CHECK: retsp 0 + ret void +} + + +declare void @llvm.va_start(i8*) nounwind +declare void @llvm.va_end(i8*) nounwind +declare void @f(i32) nounwind +define void @test_vararg(...) nounwind { +entry: +; CHECK-LABEL: test_vararg +; CHECK: extsp 6 +; CHECK: stw lr, sp[1] +; CHECK: stw r0, sp[3] +; CHECK: stw r1, sp[4] +; CHECK: stw r2, sp[5] +; CHECK: stw r3, sp[6] +; CHECK: ldaw r0, sp[3] +; CHECK: stw r0, sp[2] + %list = alloca i8*, align 4 + %list1 = bitcast i8** %list to i8* + call void @llvm.va_start(i8* %list1) + br label %for.cond + +; CHECK-LABEL: .LBB1_1 +; CHECK: ldw r0, sp[2] +; CHECK: add r1, r0, 4 +; CHECK: stw r1, sp[2] +; CHECK: ldw r0, r0[0] +; CHECK: bl f +; CHECK: bu .LBB1_1 +for.cond: + %0 = va_arg i8** %list, i32 + call void @f(i32 %0) + br label %for.cond + + call void @llvm.va_end(i8* %list1) + ret void +} + -- 2.34.1