[cfe-commits] r136734 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/arm-vaarg-align.c

Rafael Espindola rafael.espindola at gmail.com
Tue Aug 2 15:33:37 PDT 2011


Author: rafael
Date: Tue Aug  2 17:33:37 2011
New Revision: 136734

URL: http://llvm.org/viewvc/llvm-project?rev=136734&view=rev
Log:
Implements alignment for long long and double types in va_arg on ARM AAPCS.
Patch by Jim (Ningjie) Chen.

Added:
    cfe/trunk/test/CodeGen/arm-vaarg-align.c
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=136734&r1=136733&r2=136734&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Aug  2 17:33:37 2011
@@ -2575,7 +2575,6 @@
 
 llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                    CodeGenFunction &CGF) const {
-  // FIXME: Need to handle alignment
   llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
   llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
 
@@ -2583,6 +2582,16 @@
   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
                                                        "ap");
   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  // Handle address alignment for type alignment > 32 bits
+  uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8;
+  if (TyAlign > 4) {
+    assert((TyAlign & (TyAlign - 1)) == 0 &&
+           "Alignment is not power of 2!");
+    llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int32Ty);
+    AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1));
+    AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign - 1)));
+    Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
+  }
   llvm::Type *PTy =
     llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
   llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);

Added: cfe/trunk/test/CodeGen/arm-vaarg-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-vaarg-align.c?rev=136734&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/arm-vaarg-align.c (added)
+++ cfe/trunk/test/CodeGen/arm-vaarg-align.c Tue Aug  2 17:33:37 2011
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple arm -target-abi aapcs %s -emit-llvm -o - | FileCheck -check-prefix=AAPCS %s
+// RUN: %clang_cc1 -triple arm -target-abi apcs-gnu %s -emit-llvm -o - | FileCheck -check-prefix=APCS-GNU %s
+/* 
+ * Check that va_arg accesses stack according to ABI alignment
+ * long long and double require 8-byte alignment under AAPCS
+ * however, they only require 4-byte alignment under APCS
+ */
+long long t1(int i, ...) {
+    // AAPCS: t1
+    // APCS-GNU: t1
+    __builtin_va_list ap;
+    __builtin_va_start(ap, i);
+    // AAPCS: add i32 %{{.*}} 7
+    // AAPCS: and i32 %{{.*}} -8
+    // APCS-GNU-NOT: add i32 %{{.*}} 7
+    // APCS-GNU-NOT: and i32 %{{.*}} -8
+    long long ll = __builtin_va_arg(ap, long long);
+    __builtin_va_end(ap);
+    return ll;
+}
+double t2(int i, ...) {
+    // AAPCS: t2
+    // APCS-GNU: t2
+    __builtin_va_list ap;
+    __builtin_va_start(ap, i);
+    // AAPCS: add i32 %{{.*}} 7
+    // AAPCS: and i32 %{{.*}} -8
+    // APCS-GNU-NOT: add i32 %{{.*}} 7
+    // APCS-GNU-NOT: and i32 %{{.*}} -8
+    double ll = __builtin_va_arg(ap, double);
+    __builtin_va_end(ap);
+    return ll;
+}





More information about the cfe-commits mailing list