From 06d81dbad5c0c6d50141b5ade1a47def1bf4a9f4 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 1 Aug 2014 10:29:21 +0000 Subject: [PATCH] [mips] Defer va_arg expansion to the backend. Summary: This patch causes clang to emit va_arg instructions to the backend instead of expanding them into an implementation itself. The backend already implements va_arg since this is necessary for NaCl so this patch is removing redundant code. Together with the llvm patch (D4556) that accounts for the effect of endianness on the expansion of va_arg, this fixes PR19612. Depends on D4556 Reviewers: sstankovic, dsanders Reviewed By: dsanders Subscribers: rnk, cfe-commits Differential Revision: http://reviews.llvm.org/D4742 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214497 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 34 +--------------------------------- test/CodeGen/mips-vaarg.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 33 deletions(-) create mode 100644 test/CodeGen/mips-vaarg.c diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index ca99ba580a..3870f72487 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -5560,39 +5560,7 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - 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; + return nullptr; } bool diff --git a/test/CodeGen/mips-vaarg.c b/test/CodeGen/mips-vaarg.c new file mode 100644 index 0000000000..f685ed8d99 --- /dev/null +++ b/test/CodeGen/mips-vaarg.c @@ -0,0 +1,29 @@ +// 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; +} -- 2.40.0