[llvm-branch-commits] [cfe-branch] r354248 - Merging r354147:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 18 01:33:35 PST 2019


Author: hans
Date: Mon Feb 18 01:33:35 2019
New Revision: 354248

URL: http://llvm.org/viewvc/llvm-project?rev=354248&view=rev
Log:
Merging r354147:
------------------------------------------------------------------------
r354147 | jfb | 2019-02-15 18:26:29 +0100 (Fri, 15 Feb 2019) | 27 lines

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/branches/release_80/   (props changed)
    cfe/branches/release_80/lib/CodeGen/CGDecl.cpp
    cfe/branches/release_80/test/CodeGenCXX/trivial-auto-var-init.cpp

Propchange: cfe/branches/release_80/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 18 01:33:35 2019
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:351334,351340,351344,351360,351457,351459,351531,351579-351580,352040,352079,352099,352102,352105,352156,352221-352222,352229,352307,352323,352463,352539,352610,352672,352822,353142,353393,353402,353411,353431,353493,353495,353656,353943,353976,354035,354074
+/cfe/trunk:351334,351340,351344,351360,351457,351459,351531,351579-351580,352040,352079,352099,352102,352105,352156,352221-352222,352229,352307,352323,352463,352539,352610,352672,352822,353142,353393,353402,353411,353431,353493,353495,353656,353943,353976,354035,354074,354147
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_80/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/lib/CodeGen/CGDecl.cpp?rev=354248&r1=354247&r2=354248&view=diff
==============================================================================
--- cfe/branches/release_80/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/release_80/lib/CodeGen/CGDecl.cpp Mon Feb 18 01:33:35 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);
@@ -1745,10 +1746,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/branches/release_80/test/CodeGenCXX/trivial-auto-var-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/test/CodeGenCXX/trivial-auto-var-init.cpp?rev=354248&r1=354247&r2=354248&view=diff
==============================================================================
--- cfe/branches/release_80/test/CodeGenCXX/trivial-auto-var-init.cpp (original)
+++ cfe/branches/release_80/test/CodeGenCXX/trivial-auto-var-init.cpp Mon Feb 18 01:33:35 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);
   });
 }
 




More information about the llvm-branch-commits mailing list