From 2ef3cdd3d5495b2ae1faa4d575466728ecfcf0cf Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 1 Aug 2014 13:26:28 +0000 Subject: [PATCH] Revert r214497: [mips] Defer va_arg expansion to the backend. It appears that the backend does not handle all cases that were handled by clang. In particular, it does not handle structs as used in SingleSource/UnitTests/2003-05-07-VarArgs. llvm-svn: 214512 --- clang/lib/CodeGen/TargetInfo.cpp | 34 +++++++++++++++++++++++++++++++- clang/test/CodeGen/mips-vaarg.c | 29 --------------------------- 2 files changed, 33 insertions(+), 30 deletions(-) delete mode 100644 clang/test/CodeGen/mips-vaarg.c diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 3870f72487d9..ca99ba580a57 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5560,7 +5560,39 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - return nullptr; + llvm::Type *BP = CGF.Int8PtrTy; + llvm::Type *BPP = CGF.Int8PtrPtrTy; + + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); + llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + int64_t TypeAlign = getContext().getTypeAlign(Ty) / 8; + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + llvm::Value *AddrTyped; + unsigned PtrWidth = getTarget().getPointerWidth(0); + llvm::IntegerType *IntTy = (PtrWidth == 32) ? CGF.Int32Ty : CGF.Int64Ty; + + if (TypeAlign > MinABIStackAlignInBytes) { + llvm::Value *AddrAsInt = CGF.Builder.CreatePtrToInt(Addr, IntTy); + llvm::Value *Inc = llvm::ConstantInt::get(IntTy, TypeAlign - 1); + llvm::Value *Mask = llvm::ConstantInt::get(IntTy, -TypeAlign); + llvm::Value *Add = CGF.Builder.CreateAdd(AddrAsInt, Inc); + llvm::Value *And = CGF.Builder.CreateAnd(Add, Mask); + AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy); + } + else + AddrTyped = Builder.CreateBitCast(Addr, PTy); + + llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP); + TypeAlign = std::max((unsigned)TypeAlign, MinABIStackAlignInBytes); + uint64_t Offset = + llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, TypeAlign); + llvm::Value *NextAddr = + Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(IntTy, Offset), + "ap.next"); + Builder.CreateStore(NextAddr, VAListAddrAsBPP); + + return AddrTyped; } bool diff --git a/clang/test/CodeGen/mips-vaarg.c b/clang/test/CodeGen/mips-vaarg.c deleted file mode 100644 index f685ed8d997d..000000000000 --- a/clang/test/CodeGen/mips-vaarg.c +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang -target mips-unknown-linux -S -o - -emit-llvm %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s -// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s -// RUN: %clang -target mips64-unknown-linux -S -o - -emit-llvm %s -mabi=n32 | FileCheck --check-prefix=ALL --check-prefix=N32 %s -// RUN: %clang -target mips64el-unknown-linux -S -o - -emit-llvm %s -mabi=n32 | FileCheck --check-prefix=ALL --check-prefix=N32 %s -// RUN: %clang -target mips64-unknown-linux -S -o - -emit-llvm %s -mabi=64 | FileCheck --check-prefix=ALL --check-prefix=N64 %s -// RUN: %clang -target mips64el-unknown-linux -S -o - -emit-llvm %s -mabi=64 | FileCheck --check-prefix=ALL --check-prefix=N64 %s - -int foo (int a, ...) -{ - // ALL-LABEL: define i32 @foo(i32 %a, ...) - - __builtin_va_list va; - // O32: %va = alloca i8*, align 4 - // N32: %va = alloca i8*, align 4 - // N64: %va = alloca i8*, align 8 - - __builtin_va_start (va, a); - // ALL: %va1 = bitcast i8** %va to i8* - // ALL: call void @llvm.va_start(i8* %va1) - - int n = __builtin_va_arg (va, int); - // ALL: %{{[0-9]+}} = va_arg i8** %va, i32 - - __builtin_va_end (va); - // ALL: %va2 = bitcast i8** %va to i8* - // ALL: call void @llvm.va_end(i8* %va2) - - return n; -}