This patch fixes SingleSource/UnitTests/2003-05-07-VarArgs.c test on
arm-linux-gnueabi.

Lauro
Index: gcc/llvm-abi.h
===================================================================
--- gcc/llvm-abi.h	(revision 285)
+++ gcc/llvm-abi.h	(working copy)
@@ -32,6 +32,7 @@
 #include "llvm-internal.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Target/TargetData.h"
 
 namespace llvm {
   class BasicBlock;
@@ -274,17 +275,32 @@
   /// of the struct elements in.
   void PassInIntegerRegisters(tree type, const Type *Ty) {
     unsigned Size = TREE_INT_CST_LOW(TYPE_SIZE(type))/8;
-    
+
+    // FIXME: We should preserve all aggregate value alignment information.
+
+    // Work around to preserve some aggregate value alignment information:
+    // don't bitcast aggregate value to Int64 if its alignment is different
+    // from Int64 alignment. ARM backend needs this.
+    unsigned Align = TYPE_ALIGN(type)/8;
+    unsigned Int64Align = getTargetData().getABITypeAlignment(Type::Int64Ty);
+    bool UseInt64 = (Int64Align == Align);
+
     // FIXME: In cases where we can, we should use the original struct.
     // Consider cases like { int, int } and {int, short} for example!  This will
     // produce far better LLVM code!
     std::vector<const Type*> Elts;
-    for (; Size >= 8; Size -= 8)
-      Elts.push_back(Type::Int64Ty);
-    if (Size >= 4) {
-      Elts.push_back(Type::Int32Ty);
-      Size -= 4;
+    if (UseInt64) {
+      for (; Size >= 8; Size -= 8)
+        Elts.push_back(Type::Int64Ty);
+      if (Size >= 4) {
+        Elts.push_back(Type::Int32Ty);
+        Size -= 4;
+      }
+    } else {
+      for (; Size >= 4; Size -= 4)
+        Elts.push_back(Type::Int32Ty);
     }
+
     if (Size >= 2) {
       Elts.push_back(Type::Int16Ty);
       Size -= 2;
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to