[llvm-commits] [llvm-gcc-4.2] r51713 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/rs6000/llvm-rs6000.cpp llvm-abi.h
Dale Johannesen
dalej at apple.com
Thu May 29 16:00:20 PDT 2008
Author: johannes
Date: Thu May 29 18:00:20 2008
New Revision: 51713
URL: http://llvm.org/viewvc/llvm-project?rev=51713&view=rev
Log:
Fix for x86-64 ABI
struct { long x; } __attribute__((aligned(16)))
is a 16 byte object but only the 8 bytes with information
are supposed to get passed as a parameter. Hack this
using isSingleElementStructOrArray for the moment, although
I don't think that's sufficient for the general case.
No functional change for any other target.
gcc.dg/compat/struct-layout-1.exp/t001 etc.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=51713&r1=51712&r2=51713&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Thu May 29 18:00:20 2008
@@ -95,9 +95,18 @@
considered as if they were the type of the data field. */
#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
- isSingleElementStructOrArray(X, true, false)
+ isSingleElementStructOrArray(X, true, false, false)
#endif
+/* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
+ value should be passed in integer registers. This differs from the usual
+ handling in that x86-64 passes single-int-element unions as the type of the
+ field. */
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \
+ (TARGET_64BIT ? \
+ !isSingleElementStructOrArray((X), true, true, true) : \
+ !isSingleElementStructOrArray((X), false, true, false))
+
extern bool llvm_x86_should_pass_vector_in_integer_regs(tree);
/* LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp?rev=51713&r1=51712&r2=51713&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp Thu May 29 18:00:20 2008
@@ -404,7 +404,7 @@
// some zero-length fields as well, must be passed as the field type.
// Note this does not apply to long double.
// This is required for ABI correctness.
- tree tType = isSingleElementStructOrArray(TreeType, true, false);
+ tree tType = isSingleElementStructOrArray(TreeType, true, false, false);
if (tType && int_size_in_bytes(tType)==Bytes && TYPE_MODE(tType)!=TFmode &&
(TREE_CODE(tType)!=VECTOR_TYPE || Bytes==16))
return false;
@@ -437,7 +437,7 @@
// Other single-element structs may be passed this way as well, but
// only if the type size matches the element's type size (structs that
// violate this can be created with __aligned__).
- tree tType = isSingleElementStructOrArray(TreeType, true, false);
+ tree tType = isSingleElementStructOrArray(TreeType, true, false, false);
if (tType && int_size_in_bytes(tType)==SrcSize && TYPE_MODE(tType)!=TFmode &&
(TREE_CODE(tType)!=VECTOR_TYPE || SrcSize==16)) {
Elts.push_back(ConvertType(tType));
Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=51713&r1=51712&r2=51713&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu May 29 18:00:20 2008
@@ -138,17 +138,21 @@
/// rejectFatBitField, and the single element is a bitfield of a type that's
/// bigger than the struct, return null anyway.
static tree isSingleElementStructOrArray(tree type, bool ignoreZeroLength,
- bool rejectFatBitfield) {
+ bool rejectFatBitfield,
+ bool acceptUnions) {
// Scalars are good.
if (!isAggregateTreeType(type)) return type;
tree FoundField = 0;
switch (TREE_CODE(type)) {
case QUAL_UNION_TYPE:
- case UNION_TYPE: // Single element unions don't count.
case COMPLEX_TYPE: // Complex values are like 2-element records.
default:
return 0;
+ case UNION_TYPE: // Single element unions don't count.
+ if (!acceptUnions)
+ return 0;
+ // fall through
case RECORD_TYPE:
// If this record has variable length, reject it.
if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
@@ -174,13 +178,15 @@
}
}
return FoundField ? isSingleElementStructOrArray(FoundField,
- ignoreZeroLength, false)
+ ignoreZeroLength, false,
+ false)
: 0;
case ARRAY_TYPE:
const ArrayType *Ty = dyn_cast<ArrayType>(ConvertType(type));
if (!Ty || Ty->getNumElements() != 1)
return 0;
- return isSingleElementStructOrArray(TREE_TYPE(type), false, false);
+ return isSingleElementStructOrArray(TREE_TYPE(type), false, false,
+ false);
}
}
@@ -278,7 +284,7 @@
// for field-by-field struct passing does not handle this one right.
#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \
- !isSingleElementStructOrArray(X, false, true)
+ !isSingleElementStructOrArray(X, false, true, false)
#endif
// LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if this single
@@ -289,7 +295,7 @@
// by abusing the __aligned__ attribute.)
#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
- isSingleElementStructOrArray(X, false, false)
+ isSingleElementStructOrArray(X, false, false, false)
#endif
// LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this vector type
More information about the llvm-commits
mailing list