[cfe-commits] r155305 - in /cfe/trunk: lib/CodeGen/CodeGenFunction.cpp test/CodeGenCXX/global-array-destruction.cpp

Meador Inge meadori at gmail.com
Wed Apr 25 11:59:07 PDT 2012


Hi Richard,

On Sun, Apr 22, 2012 at 12:51 AM, Richard Smith
<richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Sun Apr 22 00:51:36 2012
> New Revision: 155305
>
> URL: http://llvm.org/viewvc/llvm-project?rev=155305&view=rev
> Log:
> PR12571: Objects of type clang::ConstantArrayType aren't always emitted with
> type llvm::ArrayType -- sometimes we emit them as packed structs. Don't assert
> if such a global array has an element type with a non-trivial destructor.

I was poking around at PR 12571 and am curious about something.  My first
inclination was to do exactly what did: fix 'CodeGenFunction::emitArrayLength'
to handle structures.  Then I got to wondering how structures ever end up there
to begin with.

This is what found:

1. 'CodeGenModule::EmitGlobalVarDefinition' calls 'EmitConstantInit'
    to create the intialization constant for 'A a[] = { 0 };'.

2. When calling 'EmitConstantInit' we end up in 'ConstStructBuilder::Finalize'
    which decides to use '{ i32*, i32, [4 x i8] }' (the one the builder created)
    for the constant type instead of '%class.A = type { i32*, i32 }'.

The '{ i32*, i32, [4 x i8] }' and '%class.A = type { i32*, i32 }' types are seen
as having different layouts because the tail padding is explicit in the latter.
Is this right?  I would think that class.A should have the tail padding too and
that the layouts should be identical.  (NOTE: because of this the original ICE
can be reproduced using any case similar to the original that causes the tail
padding to be added).

> Modified:
>    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>    cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=155305&r1=155304&r2=155305&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sun Apr 22 00:51:36 2012
> @@ -881,33 +881,49 @@
>   llvm::ConstantInt *zero = Builder.getInt32(0);
>   gepIndices.push_back(zero);
>
> -  // It's more efficient to calculate the count from the LLVM
> -  // constant-length arrays than to re-evaluate the array bounds.
>   uint64_t countFromCLAs = 1;
> +  QualType eltType;
>
>   llvm::ArrayType *llvmArrayType =
> -    cast<llvm::ArrayType>(
> +    dyn_cast<llvm::ArrayType>(
>       cast<llvm::PointerType>(addr->getType())->getElementType());
> -  while (true) {
> +  while (llvmArrayType) {
>     assert(isa<ConstantArrayType>(arrayType));
>     assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
>              == llvmArrayType->getNumElements());
>
>     gepIndices.push_back(zero);
>     countFromCLAs *= llvmArrayType->getNumElements();
> +    eltType = arrayType->getElementType();
>
>     llvmArrayType =
>       dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
> -    if (!llvmArrayType) break;
> -
>     arrayType = getContext().getAsArrayType(arrayType->getElementType());
> -    assert(arrayType && "LLVM and Clang types are out-of-synch");
> +    assert((!llvmArrayType || arrayType) &&
> +           "LLVM and Clang types are out-of-synch");
>   }
>
> -  baseType = arrayType->getElementType();
> +  if (arrayType) {
> +    // From this point onwards, the Clang array type has been emitted
> +    // as some other type (probably a packed struct). Compute the array
> +    // size, and just emit the 'begin' expression as a bitcast.
> +    while (arrayType) {
> +      countFromCLAs *=
> +          cast<ConstantArrayType>(arrayType)->getSize().getZExtValue();
> +      eltType = arrayType->getElementType();
> +      arrayType = getContext().getAsArrayType(eltType);
> +    }
> +
> +    unsigned AddressSpace =
> +        cast<llvm::PointerType>(addr->getType())->getAddressSpace();
> +    llvm::Type *BaseType = ConvertType(eltType)->getPointerTo(AddressSpace);
> +    addr = Builder.CreateBitCast(addr, BaseType, "array.begin");
> +  } else {
> +    // Create the actual GEP.
> +    addr = Builder.CreateInBoundsGEP(addr, gepIndices, "array.begin");
> +  }
>
> -  // Create the actual GEP.
> -  addr = Builder.CreateInBoundsGEP(addr, gepIndices, "array.begin");
> +  baseType = eltType;
>
>   llvm::Value *numElements
>     = llvm::ConstantInt::get(SizeTy, countFromCLAs);
>
> Modified: cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp?rev=155305&r1=155304&r2=155305&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/global-array-destruction.cpp Sun Apr 22 00:51:36 2012
> @@ -1,6 +1,4 @@
> -// REQUIRES: x86-64-registered-target
> -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
> -// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
>
>  extern "C" int printf(...);
>
> @@ -24,11 +22,24 @@
>  S s2;
>  S arr3[3];
>
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> -// CHECK-LP64: callq    ___cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: call {{.*}} @__cxa_atexit
> +
> +struct T {
> +  double d;
> +  int n;
> +  ~T();
> +};
> +T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
> +
> +// CHECK: call {{.*}} @__cxa_atexit
> +// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @t to %struct.T*), i64 6
> +// CHECK: call void @_ZN1TD1Ev
> +// CHECK: icmp eq {{.*}} @t
> +// CHECK: br i1 {{.*}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



-- 
# Meador




More information about the cfe-commits mailing list