From: Daniel Sanders <daniel.sanders@imgtec.com>
Date: Fri, 1 Aug 2014 13:26:28 +0000 (+0000)
Subject: Revert r214497: [mips] Defer va_arg expansion to the backend.
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=343298a5276fdf025c951f4a2a1778e05a0993bd;p=clang

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.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214512 91177308-0d34-0410-b5e6-96231b3b80d8
---

diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 3870f72487..ca99ba580a 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/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/test/CodeGen/mips-vaarg.c b/test/CodeGen/mips-vaarg.c
deleted file mode 100644
index f685ed8d99..0000000000
--- a/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;
-}