[llvm-commits] [llvm-gcc-4.2] r51723 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp config/rs6000/llvm-rs6000.cpp llvm-abi.h
Evan Cheng
evan.cheng at apple.com
Mon Jun 2 17:35:41 PDT 2008
Hi Dale,
Looks like this patch broke 447.dealII on x86-64. Try this:
make ENABLE_OPTIMIZED=1 TEST=nightly TARGET_FLAGS="-m64 -
DSPEC_CPU2000_LP64 -DSPEC_CPU_LP64" TARGET_LLCFLAGS="-relocation-
model=pic -disable-fp-elim" EXTRA_LLI_OPTS="-relocation-model=pic -
disable-fp-elim" clean Output/447.dealII.diff-llc
Evan
On May 29, 2008, at 6:23 PM, Dale Johannesen wrote:
> Author: johannes
> Date: Thu May 29 20:23:12 2008
> New Revision: 51723
>
> URL: http://llvm.org/viewvc/llvm-project?rev=51723&view=rev
> Log:
> X86-64 ABI fix. Revert isSingleElementStructOrArray
> change in favor of a more general version which handles
> the case where there's more than one element correctly.
> Fixes gcc.dg/compat/struct-layout-1.exp/t003
> and many more.
>
>
> Modified:
> llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
> llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
> 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=51723&r1=51722&r2=51723&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
> 20:23:12 2008
> @@ -95,17 +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, false)
> + isSingleElementStructOrArray(X, true, false)
> #endif
>
> +extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree,
> unsigned*);
> +
> /* 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))
> + handling in that x86-64 passes 128-bit structs and unions which
> only
> + contain data in the first 64 bits, as 64-bit objects. (These
> can be
> + created by abusing __attribute__((aligned)). */
> +#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X,
> Y) \
> + llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y))
>
> extern bool llvm_x86_should_pass_vector_in_integer_regs(tree);
>
>
> Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=51723&r1=51722&r2=51723&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
> +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Thu May 29
> 20:23:12 2008
> @@ -1288,4 +1288,38 @@
> return Loc;
> }
>
> +/// llvm_x86_should_pass_aggregate_in_integer_regs - x86-32 is same
> as the
> +/// default. x86-64 detects the case where a type is 16 bytes long
> but
> +/// only 8 of them are passed, the rest being padding (*size is set
> to 8
> +/// to identify this case).
> +bool llvm_x86_should_pass_aggregate_in_integer_regs(tree type,
> unsigned *size)
> +{
> + *size = 0;
> + if (TARGET_64BIT) {
> + enum x86_64_reg_class Class[MAX_CLASSES];
> + enum machine_mode Mode = ix86_getNaturalModeForType(type);
> + int NumClasses = ix86_ClassifyArgument(Mode, type, Class, 0);
> + if (NumClasses == 1 && (Class[0] == X86_64_INTEGERSI_CLASS ||
> + Class[0] == X86_64_INTEGER_CLASS)) {
> + /* 8 byte object, one int register */
> + return true;
> + }
> + if (NumClasses == 2 && (Class[0] == X86_64_INTEGERSI_CLASS ||
> + Class[0] == X86_64_INTEGER_CLASS)) {
> + if (Class[1] == X86_64_INTEGERSI_CLASS ||
> + Class[1] == X86_64_INTEGER_CLASS)
> + /* 16 byte object, 2 int registers */
> + return true;
> + if (Class[1] == X86_64_NO_CLASS) {
> + /* 16 byte object, only 1st register has information */
> + *size = 8;
> + return true;
> + }
> + }
> + return false;
> + }
> + else
> + return !isSingleElementStructOrArray(type, false, true);
> +}
> +
> /* LLVM LOCAL end (ENTIRE FILE!) */
>
> 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=51723&r1=51722&r2=51723&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
> 20:23:12 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,
> false);
> + tree tType = isSingleElementStructOrArray(TreeType, true, 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,
> false);
> + tree tType = isSingleElementStructOrArray(TreeType, true, 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=51723&r1=51722&r2=51723&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
> +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu May 29 20:23:12 2008
> @@ -138,21 +138,17 @@
> /// 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 acceptUnions) {
> + bool rejectFatBitfield) {
> // 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)
> @@ -178,15 +174,13 @@
> }
> }
> return FoundField ? isSingleElementStructOrArray(FoundField,
> -
> ignoreZeroLength, false,
> - false)
> +
> ignoreZeroLength, 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,
> - false);
> + return isSingleElementStructOrArray(TREE_TYPE(type), false,
> false);
> }
> }
>
> @@ -283,8 +277,8 @@
> // single element is a bitfield of a type bigger than the struct;
> the code
> // 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, false)
> +#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y) \
> + !isSingleElementStructOrArray((X), false, true)
> #endif
>
> // LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if
> this single
> @@ -295,7 +289,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, false)
> + isSingleElementStructOrArray(X, false, false)
> #endif
>
> // LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this
> vector type
> @@ -408,6 +402,7 @@
> /// their fields.
> void HandleArgument(tree type, std::vector<const Type*> &ScalarElts,
> ParameterAttributes *Attributes = NULL) {
> + unsigned Size = 0;
> const Type *Ty = ConvertType(type);
> // Figure out if this field is zero bits wide, e.g. {} or [0 x
> int]. Do
> // not include variable sized fields here.
> @@ -418,7 +413,7 @@
> ScalarElts.push_back(PtrTy);
> } else if (Ty->getTypeID()==Type::VectorTyID) {
> if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
> - PassInIntegerRegisters(type, Ty, ScalarElts);
> + PassInIntegerRegisters(type, Ty, ScalarElts, 0);
> } else {
> C.HandleScalarArgument(Ty, type);
> ScalarElts.push_back(Ty);
> @@ -444,8 +439,8 @@
> *Attributes |=
>
> ParamAttr::constructAlignmentFromInt(LLVM_BYVAL_ALIGNMENT(type));
> }
> - } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type)) {
> - PassInIntegerRegisters(type, Ty, ScalarElts);
> + } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type,
> &Size)) {
> + PassInIntegerRegisters(type, Ty, ScalarElts, Size);
> } else if (isZeroSizedStructOrUnion(type)) {
> // Zero sized struct or union, just drop it!
> ;
> @@ -526,10 +521,15 @@
>
> /// PassInIntegerRegisters - Given an aggregate value that should
> be passed in
> /// integer registers, convert it to a structure containing ints
> and pass all
> - /// of the struct elements in.
> + /// of the struct elements in. If Size is set we pass only that
> many bytes.
> void PassInIntegerRegisters(tree type, const Type *Ty,
> - std::vector<const Type*> &ScalarElts) {
> - unsigned Size = TREE_INT_CST_LOW(TYPE_SIZE(type))/8;
> + std::vector<const Type*> &ScalarElts,
> + unsigned origSize) {
> + unsigned Size;
> + if (origSize)
> + Size = origSize;
> + else
> + 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:
> @@ -568,7 +568,7 @@
> Elts.push_back(Type::Int8Ty);
> Size -= 1;
> }
> - assert(Size == 0 && "Didn't cover value?");
> + assert((origSize || Size == 0) && "Didn't cover value?");
> const StructType *STy = StructType::get(Elts, false);
>
> unsigned i = 0;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list