r354147 - Variable auto-init of blocks capturing self after init bugfix
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 18 01:33:00 PST 2019
Merged to release_80 in r354248.
On Fri, Feb 15, 2019 at 6:25 PM JF Bastien via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
>
> Author: jfb
> Date: Fri Feb 15 09:26:29 2019
> New Revision: 354147
>
> URL: http://llvm.org/viewvc/llvm-project?rev=354147&view=rev
> Log:
> Variable auto-init of blocks capturing self after init bugfix
>
> Summary:
> Blocks that capture themselves (and escape) after initialization currently codegen wrong because this:
>
> bool capturedByInit =
> Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
>
> Address Loc =
> capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
>
> Already adjusts Loc from thr alloca to a GEP. This code:
>
> if (emission.IsEscapingByRef)
> Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
>
> Was trying to do the same adjustment, and a GEP on a GEP (returning an int) triggers an assertion.
>
> <rdar://problem/47943027>
>
> Reviewers: ahatanak
>
> Subscribers: jkorous, dexonsmith, cfe-commits, rjmccall
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D58218
>
> Modified:
> cfe/trunk/lib/CodeGen/CGDecl.cpp
> cfe/trunk/test/CodeGenCXX/trivial-auto-var-init.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=354147&r1=354146&r2=354147&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Feb 15 09:26:29 2019
> @@ -1620,8 +1620,9 @@ void CodeGenFunction::EmitAutoVarInit(co
> bool capturedByInit =
> Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
>
> - Address Loc =
> - capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
> + bool locIsByrefHeader = !capturedByInit;
> + const Address Loc =
> + locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
>
> // Note: constexpr already initializes everything correctly.
> LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
> @@ -1637,7 +1638,7 @@ void CodeGenFunction::EmitAutoVarInit(co
> return;
>
> // Only initialize a __block's storage: we always initialize the header.
> - if (emission.IsEscapingByRef)
> + if (emission.IsEscapingByRef && !locIsByrefHeader)
> Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
>
> CharUnits Size = getContext().getTypeSizeInChars(type);
> @@ -1744,10 +1745,9 @@ void CodeGenFunction::EmitAutoVarInit(co
> }
>
> llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
> - if (Loc.getType() != BP)
> - Loc = Builder.CreateBitCast(Loc, BP);
> -
> - emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
> + emitStoresForConstant(
> + CGM, D, (Loc.getType() == BP) ? Loc : Builder.CreateBitCast(Loc, BP),
> + isVolatile, Builder, constant);
> }
>
> /// Emit an expression as an initializer for an object (variable, field, etc.)
>
> Modified: cfe/trunk/test/CodeGenCXX/trivial-auto-var-init.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/trivial-auto-var-init.cpp?rev=354147&r1=354146&r2=354147&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/trivial-auto-var-init.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/trivial-auto-var-init.cpp Fri Feb 15 09:26:29 2019
> @@ -45,14 +45,35 @@ void test_block() {
> // PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
> // PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
> // PATTERN: %call = call %struct.XYZ* @create(
> +using Block = void (^)();
> +typedef struct XYZ {
> + Block block;
> +} * xyz_t;
> void test_block_self_init() {
> - using Block = void (^)();
> - typedef struct XYZ {
> - Block block;
> - } * xyz_t;
> extern xyz_t create(Block block);
> __block xyz_t captured = create(^() {
> - (void)captured;
> + used(captured);
> + });
> +}
> +
> +// Capturing with escape after initialization is also an edge case.
> +//
> +// UNINIT-LABEL: test_block_captures_self_after_init(
> +// ZERO-LABEL: test_block_captures_self_after_init(
> +// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
> +// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
> +// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
> +// ZERO: %call = call %struct.XYZ* @create(
> +// PATTERN-LABEL: test_block_captures_self_after_init(
> +// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
> +// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
> +// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
> +// PATTERN: %call = call %struct.XYZ* @create(
> +void test_block_captures_self_after_init() {
> + extern xyz_t create(Block block);
> + __block xyz_t captured;
> + captured = create(^() {
> + used(captured);
> });
> }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list