[PATCH] [mips] Defer va_arg expansion to the backend.

Daniel Sanders daniel.sanders at imgtec.com
Thu Jul 31 11:38:27 PDT 2014


Expanded on the test case as Reid suggested and accounted for different
alignment requirements of the pointer between the N32 and N64 ABI's.

http://reviews.llvm.org/D4742

Files:
  lib/CodeGen/TargetInfo.cpp
  test/CodeGen/mips-vaarg.c

Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -5560,39 +5560,7 @@
 
 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
Index: test/CodeGen/mips-vaarg.c
===================================================================
--- /dev/null
+++ 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;
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4742.12076.patch
Type: text/x-patch
Size: 3386 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140731/9963edfd/attachment.bin>


More information about the cfe-commits mailing list