From 253145299b3f165522ed2a85a837ed22c38825c6 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Wed, 22 Jun 2005 21:04:42 +0000 Subject: [PATCH] If we support structs as va_list, we must pass pointers to them to va_copy See last commit for LangRef, this implements it on all targets. llvm-svn: 22273 --- llvm/lib/AsmParser/llvmAsmParser.y | 27 +++++++++++-------- llvm/lib/Bytecode/Reader/ReaderWrappers.cpp | 12 ++++++--- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 9 ++++--- llvm/lib/Target/CBackend/Writer.cpp | 2 +- llvm/lib/Target/IA64/IA64ISelPattern.cpp | 13 --------- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp | 14 ---------- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp | 17 ++++++++---- llvm/lib/Target/X86/X86ISelPattern.cpp | 13 --------- 8 files changed, 42 insertions(+), 65 deletions(-) diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index b71f618779be..178c53309346 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -749,14 +749,12 @@ static PATypeHolder HandleUpRefs(const Type *ty) { } if (ObsoleteVarArgs && NewVarArgs) - { - std::cerr << "This file is corrupt in that it uses both new and old style varargs\n"; - abort(); - } + ThrowException("This file is corrupt in that it uses both new and old style varargs"); if(ObsoleteVarArgs) { if(Function* F = Result->getNamedFunction("llvm.va_start")) { - assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); + if (F->arg_size() != 0) + ThrowException("Obsolete va_start takes 0 argument!"); //foo = va_start() // -> @@ -782,7 +780,9 @@ static PATypeHolder HandleUpRefs(const Type *ty) { } if(Function* F = Result->getNamedFunction("llvm.va_end")) { - assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!"); + if(F->arg_size() != 1) + ThrowException("Obsolete va_end takes 1 argument!"); + //vaend foo // -> //bar = alloca 1 of typeof(foo) @@ -804,24 +804,29 @@ static PATypeHolder HandleUpRefs(const Type *ty) { } if(Function* F = Result->getNamedFunction("llvm.va_copy")) { - assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!"); + if(F->arg_size() != 1) + ThrowException("Obsolete va_copy takes 1 argument!"); //foo = vacopy(bar) // -> //a = alloca 1 of typeof(foo) - //vacopy(a, bar) + //b = alloca 1 of typeof(foo) + //store bar -> b + //vacopy(a, b) //foo = load a const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_copy", - RetTy, ArgTyPtr, ArgTy, 0); + RetTy, ArgTyPtr, ArgTyPtr, 0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); - new CallInst(NF, a, CI->getOperand(1), "", CI); - Value* foo = new LoadInst(a, "vacopy.fix.2", CI); + AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI); + new StoreInst(CI->getOperand(1), b, CI); + new CallInst(NF, a, b, "", CI); + Value* foo = new LoadInst(a, "vacopy.fix.3", CI); CI->replaceAllUsesWith(foo); CI->getParent()->getInstList().erase(CI); } diff --git a/llvm/lib/Bytecode/Reader/ReaderWrappers.cpp b/llvm/lib/Bytecode/Reader/ReaderWrappers.cpp index c000c9a3f592..a198447d72c1 100644 --- a/llvm/lib/Bytecode/Reader/ReaderWrappers.cpp +++ b/llvm/lib/Bytecode/Reader/ReaderWrappers.cpp @@ -221,20 +221,24 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) { //foo = vacopy(bar) // -> //a = alloca 1 of typeof(foo) - //vacopy(a, bar) + //b = alloca 1 of typeof(foo) + //store bar -> b + //vacopy(a, b) //foo = load a const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = M->getOrInsertFunction("llvm.va_copy", - RetTy, ArgTyPtr, ArgTy, 0); + RetTy, ArgTyPtr, ArgTyPtr, 0); for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) if (CallInst* CI = dyn_cast(*I++)) { AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); - new CallInst(NF, a, CI->getOperand(1), "", CI); - Value* foo = new LoadInst(a, "vacopy.fix.2", CI); + AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI); + new StoreInst(CI->getOperand(1), b, CI); + new CallInst(NF, a, b, "", CI); + Value* foo = new LoadInst(a, "vacopy.fix.3", CI); CI->replaceAllUsesWith(foo); CI->getParent()->getInstList().erase(CI); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 0c94ea74cd9d..fa6d6d4d14cd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -855,10 +855,11 @@ SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand L, std::pair TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, SelectionDAG &DAG) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments handling not implemented on this target!\n"; - abort(); + //Default to returning the input list + SDOperand Val = DAG.getLoad(getPointerTy(), Chain, Src, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), + Val, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); } std::pair diff --git a/llvm/lib/Target/CBackend/Writer.cpp b/llvm/lib/Target/CBackend/Writer.cpp index 65979933dbb5..c30b306483e4 100644 --- a/llvm/lib/Target/CBackend/Writer.cpp +++ b/llvm/lib/Target/CBackend/Writer.cpp @@ -1495,7 +1495,7 @@ void CWriter::visitCallInst(CallInst &I) { Out << "0; "; Out << "va_copy(*(va_list*)"; writeOperand(I.getOperand(1)); - Out << ", *(va_list*)&"; + Out << ", *(va_list*)"; writeOperand(I.getOperand(2)); Out << ')'; return; diff --git a/llvm/lib/Target/IA64/IA64ISelPattern.cpp b/llvm/lib/Target/IA64/IA64ISelPattern.cpp index 0830468a959b..804ad9937ef6 100644 --- a/llvm/lib/Target/IA64/IA64ISelPattern.cpp +++ b/llvm/lib/Target/IA64/IA64ISelPattern.cpp @@ -120,10 +120,6 @@ namespace { LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair - LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -413,15 +409,6 @@ LowerVAArgNext(SDOperand Chain, SDOperand VAList, return std::make_pair(Result, Chain); } -std::pair -IA64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, - SDOperand Dest, SelectionDAG &DAG) -{ - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Src, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); -} - std::pair IA64TargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { diff --git a/llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp index 20fd7244447b..6761ab1115cb 100644 --- a/llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp +++ b/llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp @@ -104,10 +104,6 @@ namespace { LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair - LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -390,16 +386,6 @@ LowerVAArgNext(SDOperand Chain, SDOperand VAList, return std::make_pair(Result, Chain); } -std::pair -PPC64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, - SDOperand Dest, SelectionDAG &DAG) -{ - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Src, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); -} - - std::pair PPC64TargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { diff --git a/llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp b/llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp index cc2c81f3bb77..a6722b1862f4 100644 --- a/llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp +++ b/llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp @@ -2881,11 +2881,18 @@ static bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr, return true; // no-op on SparcV9 case Intrinsic::vacopy: - // Simple store of current va_list (arg2) to new va_list (arg1) - mvec.push_back(BuildMI(V9::STXi, 3). - addReg(callInstr.getOperand(2)). - addReg(callInstr.getOperand(1)).addSImm(0)); - return true; + { + MachineCodeForInstruction& m1 = MachineCodeForInstruction::get(&callInstr); + TmpInstruction* VReg = + new TmpInstruction(m1, callInstr.getOperand(1)->getType()); + + // Simple store of current va_list (arg2) to new va_list (arg1) + mvec.push_back(BuildMI(V9::LDXi, 3). + addReg(callInstr.getOperand(2)).addSImm(0).addRegDef(VReg)); + mvec.push_back(BuildMI(V9::STXi, 3). + addReg(VReg).addReg(callInstr.getOperand(1)).addSImm(0)); + return true; + } } } diff --git a/llvm/lib/Target/X86/X86ISelPattern.cpp b/llvm/lib/Target/X86/X86ISelPattern.cpp index d28de2828d65..e858c4c82125 100644 --- a/llvm/lib/Target/X86/X86ISelPattern.cpp +++ b/llvm/lib/Target/X86/X86ISelPattern.cpp @@ -182,10 +182,6 @@ namespace { LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair - LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -475,15 +471,6 @@ X86TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList, return std::make_pair(Result, Chain); } -std::pair -X86TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, - SDOperand Dest, SelectionDAG &DAG) -{ - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Src, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); -} - //===----------------------------------------------------------------------===// // Fast Calling Convention implementation //===----------------------------------------------------------------------===//