[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-10-30 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia added a comment.

In https://reviews.llvm.org/D43783#1272001, @AlexeySotkin wrote:

> In https://reviews.llvm.org/D43783#1215573, @Anastasia wrote:
>
> > In https://reviews.llvm.org/D43783#1212485, @yaxunl wrote:
> >
> > > In https://reviews.llvm.org/D43783#1204353, @svenvh wrote:
> > >
> > > > Sorry for digging up an old commit...
> > > >
> > > > Apparently this broke block arguments, e.g. the following test case:
> > > >
> > > >   int foo(int (^ bl)(void)) {
> > > > return bl();
> > > >   }
> > > >  
> > > >   int get21() {
> > > > return foo(^{return 21;});
> > > >   }
> > > >  
> > > >   int get42() {
> > > > return foo(^{return 42;});
> > > >   }
> > > >
> > > >
> > > > In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
> > > > initializer when the called block comes from an argument (causing clang 
> > > > to crash).
> > >
> > >
> > > Sorry for the delay. I think block should not be allowed as function 
> > > argument since this generally leads indirect function calls therefore 
> > > requires support of function pointer. It will rely on optimizations to 
> > > get rid of indirect function calls.
> >
> >
> > The idea was to allow blocks as function parameters because they are 
> > statically known at each function call. This can be resolved later at IR 
> > level instead of frontend. I am also not sure there can be other corner 
> > cases where it wouldn't work in Clang since we can't leverage analysis 
> > passes here. I feel this might be a risky thing to do in Clang. Currently 
> > it doesn't work for the examples provided and therefore breaking the 
> > compliance with the spec.
>
>
> The spec is not clear about what is "statically determinable". To me, in the 
> example provided we can not resolve the `bl()` call without inlining `foo`, 
> even at IR level. As Sam noted, that leads to indirect call and require 
> support of functions pointers.
>  I see a contradiction in the spec in allowing blocks to be a function 
> argument and disallowing function pointers at the same time. I think maybe 
> the spec should be changed to clarify existing restrictions or add more 
> restrictions for cases when blocks are passed as function argument.


I am  not sure that blocks in function call parameters contradict the rule of 
them being statically determinable though. You can statically determine what 
blocks are being passed into a function. There might be multiple different ones 
though. However, it should be possible to lower the function pointers into the 
direct calls.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-10-23 Thread Alexey Sotkin via Phabricator via cfe-commits
AlexeySotkin added a comment.

In https://reviews.llvm.org/D43783#1215573, @Anastasia wrote:

> In https://reviews.llvm.org/D43783#1212485, @yaxunl wrote:
>
> > In https://reviews.llvm.org/D43783#1204353, @svenvh wrote:
> >
> > > Sorry for digging up an old commit...
> > >
> > > Apparently this broke block arguments, e.g. the following test case:
> > >
> > >   int foo(int (^ bl)(void)) {
> > > return bl();
> > >   }
> > >  
> > >   int get21() {
> > > return foo(^{return 21;});
> > >   }
> > >  
> > >   int get42() {
> > > return foo(^{return 42;});
> > >   }
> > >
> > >
> > > In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
> > > initializer when the called block comes from an argument (causing clang 
> > > to crash).
> >
> >
> > Sorry for the delay. I think block should not be allowed as function 
> > argument since this generally leads indirect function calls therefore 
> > requires support of function pointer. It will rely on optimizations to get 
> > rid of indirect function calls.
>
>
> The idea was to allow blocks as function parameters because they are 
> statically known at each function call. This can be resolved later at IR 
> level instead of frontend. I am also not sure there can be other corner cases 
> where it wouldn't work in Clang since we can't leverage analysis passes here. 
> I feel this might be a risky thing to do in Clang. Currently it doesn't work 
> for the examples provided and therefore breaking the compliance with the spec.


The spec is not clear about what is "statically determinable". To me, in the 
example provided we can not resolve the `bl()` call without inlining `foo`, 
even at IR level. As Sam noted, that leads to indirect call and require support 
of functions pointers.
I see a contradiction in the spec in allowing blocks to be a function argument 
and disallowing function pointers at the same time. I think maybe the spec 
should be changed to clarify existing restrictions or add more restrictions for 
cases when blocks are passed as function argument.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-10-02 Thread Sven van Haastregt via Phabricator via cfe-commits
svenvh added a comment.

Reverted in r343582, test added in r343583.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-09-24 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia added a comment.

In https://reviews.llvm.org/D43783#1235126, @yaxunl wrote:

> In https://reviews.llvm.org/D43783#1235090, @Anastasia wrote:
>
> > Ping! Do you still plan to do this? :)
>
>
> Sorry I caught up in something else. Since there are some subsequent commits, 
> it may take some efforts to revert it.


No problem. Let me know if help is needed. :)

In https://reviews.llvm.org/D43783#1235126, @yaxunl wrote:

> In https://reviews.llvm.org/D43783#1235090, @Anastasia wrote:
>
> > Ping! Do you still plan to do this? :)
>
>
> Sorry I caught up in something else. Since there are some subsequent commits, 
> it may take some efforts to revert it.


Let me know if you need help. I am happy to do this myself.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-09-14 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

In https://reviews.llvm.org/D43783#1235090, @Anastasia wrote:

> Ping! Do you still plan to do this? :)


Sorry I caught up in something else. Since there are some subsequent commits, 
it may take some efforts to revert it.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-09-14 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia added a comment.

Ping! Do you still plan to do this? :)


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-08-29 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

In https://reviews.llvm.org/D43783#1215573, @Anastasia wrote:

> In https://reviews.llvm.org/D43783#1212485, @yaxunl wrote:
>
> > In https://reviews.llvm.org/D43783#1204353, @svenvh wrote:
> >
> > > Sorry for digging up an old commit...
> > >
> > > Apparently this broke block arguments, e.g. the following test case:
> > >
> > >   int foo(int (^ bl)(void)) {
> > > return bl();
> > >   }
> > >  
> > >   int get21() {
> > > return foo(^{return 21;});
> > >   }
> > >  
> > >   int get42() {
> > > return foo(^{return 42;});
> > >   }
> > >
> > >
> > > In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
> > > initializer when the called block comes from an argument (causing clang 
> > > to crash).
> >
> >
> > Sorry for the delay. I think block should not be allowed as function 
> > argument since this generally leads indirect function calls therefore 
> > requires support of function pointer. It will rely on optimizations to get 
> > rid of indirect function calls.
>
>
> The idea was to allow blocks as function parameters because they are 
> statically known at each function call. This can be resolved later at IR 
> level instead of frontend. I am also not sure there can be other corner cases 
> where it wouldn't work in Clang since we can't leverage analysis passes here. 
> I feel this might be a risky thing to do in Clang. Currently it doesn't work 
> for the examples provided and therefore breaking the compliance with the spec.


I agree this patch should be reverted for conformance to spec. I will do that. 
Thanks.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-08-28 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia added a comment.

In https://reviews.llvm.org/D43783#1212485, @yaxunl wrote:

> In https://reviews.llvm.org/D43783#1204353, @svenvh wrote:
>
> > Sorry for digging up an old commit...
> >
> > Apparently this broke block arguments, e.g. the following test case:
> >
> >   int foo(int (^ bl)(void)) {
> > return bl();
> >   }
> >  
> >   int get21() {
> > return foo(^{return 21;});
> >   }
> >  
> >   int get42() {
> > return foo(^{return 42;});
> >   }
> >
> >
> > In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
> > initializer when the called block comes from an argument (causing clang to 
> > crash).
>
>
> Sorry for the delay. I think block should not be allowed as function argument 
> since this generally leads indirect function calls therefore requires support 
> of function pointer. It will rely on optimizations to get rid of indirect 
> function calls.


The idea was to allow blocks as function parameters because they are statically 
known at each function call. This can be resolved later at IR level instead of 
frontend. I am also not sure there can be other corner cases where it wouldn't 
work in Clang since we can't leverage analysis passes here. I feel this might 
be a risky thing to do in Clang. Currently it doesn't work for the examples 
provided and therefore breaking the compliance with the spec.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-08-24 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.
Herald added a subscriber: jvesely.

In https://reviews.llvm.org/D43783#1204353, @svenvh wrote:

> Sorry for digging up an old commit...
>
> Apparently this broke block arguments, e.g. the following test case:
>
>   int foo(int (^ bl)(void)) {
> return bl();
>   }
>  
>   int get21() {
> return foo(^{return 21;});
>   }
>  
>   int get42() {
> return foo(^{return 42;});
>   }
>
>
> In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
> initializer when the called block comes from an argument (causing clang to 
> crash).


Sorry for the delay. I think block should not be allowed as function argument 
since this generally leads indirect function calls therefore requires support 
of function pointer. It will rely on optimizations to get rid of indirect 
function calls.


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-08-17 Thread Sven van Haastregt via Phabricator via cfe-commits
svenvh added a comment.

Sorry for digging up an old commit...

Apparently this broke block arguments, e.g. the following test case:

  int foo(int (^ bl)(void)) {
return bl();
  }
  
  int get21() {
return foo(^{return 21;});
  }
  
  int get42() {
return foo(^{return 42;});
  }

In particular, the VarDecl that `getBlockExpr()` sees doesn't have an 
initializer when the called block comes from an argument (causing clang to 
crash).


Repository:
  rC Clang

https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-03-07 Thread Yaxun Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326937: [OpenCL] Remove block invoke function from emitted 
block literal struct (authored by yaxunl, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D43783

Files:
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenCLRuntime.h
  test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl
  test/CodeGenOpenCL/blocks.cl
  test/CodeGenOpenCL/cl20-device-side-enqueue.cl

Index: test/CodeGenOpenCL/blocks.cl
===
--- test/CodeGenOpenCL/blocks.cl
+++ test/CodeGenOpenCL/blocks.cl
@@ -1,10 +1,7 @@
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck -check-prefixes=COMMON,SPIR %s
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa | FileCheck -check-prefixes=COMMON,AMDGCN %s
 
-// SPIR: %struct.__opencl_block_literal_generic = type { i32, i32, i8 addrspace(4)* }
-// AMDGCN: %struct.__opencl_block_literal_generic = type { i32, i32, i8* }
-// SPIR: @__block_literal_global = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 12, i32 4, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* @block_A_block_invoke to i8*) to i8 addrspace(4)*) }
-// AMDGCN: @__block_literal_global = internal addrspace(1) constant { i32, i32, i8* } { i32 16, i32 8, i8* bitcast (void (i8*, i8 addrspace(3)*)* @block_A_block_invoke to i8*) }
+// COMMON: @__block_literal_global = internal addrspace(1) constant { i32, i32 } { i32 8, i32 4 }
 // COMMON-NOT: .str
 
 // SPIR-LABEL: define internal {{.*}}void @block_A_block_invoke(i8 addrspace(4)* %.block_descriptor, i8 addrspace(3)* %a)
@@ -20,58 +17,46 @@
   // COMMON-NOT: %block.flags
   // COMMON-NOT: %block.reserved
   // COMMON-NOT: %block.descriptor
-  // SPIR: %[[block_size:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %block, i32 0, i32 0
-  // AMDGCN: %[[block_size:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %block, i32 0, i32 0
-  // SPIR: store i32 16, i32* %[[block_size]]
-  // AMDGCN: store i32 20, i32 addrspace(5)* %[[block_size]]
-  // SPIR: %[[block_align:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %block, i32 0, i32 1
-  // AMDGCN: %[[block_align:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %block, i32 0, i32 1
+  // SPIR: %[[block_size:.*]] = getelementptr inbounds <{ i32, i32, i32 }>, <{ i32, i32, i32 }>* %[[block:.*]], i32 0, i32 0
+  // AMDGCN: %[[block_size:.*]] = getelementptr inbounds <{ i32, i32, i32 }>, <{ i32, i32, i32 }> addrspace(5)* %[[block:.*]], i32 0, i32 0
+  // SPIR: store i32 12, i32* %[[block_size]]
+  // AMDGCN: store i32 12, i32 addrspace(5)* %[[block_size]]
+  // SPIR: %[[block_align:.*]] = getelementptr inbounds <{ i32, i32, i32 }>, <{ i32, i32, i32 }>* %[[block]], i32 0, i32 1
+  // AMDGCN: %[[block_align:.*]] = getelementptr inbounds <{ i32, i32, i32 }>, <{ i32, i32, i32 }> addrspace(5)* %[[block]], i32 0, i32 1
   // SPIR: store i32 4, i32* %[[block_align]]
-  // AMDGCN: store i32 8, i32 addrspace(5)* %[[block_align]]
-  // SPIR: %[[block_invoke:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block:.*]], i32 0, i32 2
-  // SPIR: store i8 addrspace(4)* addrspacecast (i8* bitcast (i32 (i8 addrspace(4)*)* @__foo_block_invoke to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %[[block_invoke]]
-  // SPIR: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]], i32 0, i32 3
+  // AMDGCN: store i32 4, i32 addrspace(5)* %[[block_align]]
+  // SPIR: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i32 }>, <{ i32, i32, i32 }>* %[[block]], i32 0, i32 2
   // SPIR: %[[i_value:.*]] = load i32, i32* %i
   // SPIR: store i32 %[[i_value]], i32* %[[block_captured]],
-  // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to i32 ()*
+  // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i32 }>* %[[block]] to i32 ()*
   // SPIR: %[[blk_gen_ptr:.*]] = addrspacecast i32 ()* %[[blk_ptr]] to i32 () addrspace(4)*
   // SPIR: store i32 () addrspace(4)* %[[blk_gen_ptr]], i32 () addrspace(4)** %[[block_B:.*]],
-  // SPIR: %[[blk_gen_ptr:.*]] = load i32 () addrspace(4)*, i32 () addrspace(4)** %[[block_B]]
-  // SPIR: %[[block_literal:.*]] = bitcast i32 () addrspace(4)* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
-  // SPIR: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]], i32 0, i32 2
-  // SPIR: %[[blk_gen_ptr:.*]] = bitcast %struct._

[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-03-06 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added inline comments.



Comment at: lib/CodeGen/CGBlocks.cpp:1065-1067
+  llvm::Value *FuncPtr;
 
+  if (!CGM.getLangOpts().OpenCL) {

bader wrote:
> I think it would be more readable if we merge this if statement with the if 
> statement at the line #1103.
> It's used to initialize FuncPtr for non-OpenCL languages and the first use of 
> this variable is in the else block of if statement at the line #1103.
> If I didn't miss something it should reasonable to combine this if block with 
> 'else' block at the line #1106.
BlockPtr is used on line 1093, so it cannot be moved to line 1106.


https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-03-06 Thread Alexey Bader via Phabricator via cfe-commits
bader accepted this revision.
bader added a comment.
This revision is now accepted and ready to land.

Hi Sam,

Sorry for the delay. LGTM, I have only minor refactoring suggestion.

Thanks,
Alexey




Comment at: lib/CodeGen/CGBlocks.cpp:1065-1067
+  llvm::Value *FuncPtr;
 
+  if (!CGM.getLangOpts().OpenCL) {

I think it would be more readable if we merge this if statement with the if 
statement at the line #1103.
It's used to initialize FuncPtr for non-OpenCL languages and the first use of 
this variable is in the else block of if statement at the line #1103.
If I didn't miss something it should reasonable to combine this if block with 
'else' block at the line #1106.


https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-03-05 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

ping


https://reviews.llvm.org/D43783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43783: [OpenCL] Remove block invoke function from emitted block literal struct

2018-02-26 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.
yaxunl added reviewers: b-sumner, Anastasia, bader.
Herald added a subscriber: nhaehnle.

OpenCL runtime tracks the invoke function emitted for
any block expression. Due to restrictions on blocks in
OpenCL (v2.0 s6.12.5), it is always possible to know the
block invoke function when emitting call of block expression
or __enqueue_kernel builtin functions. Since __enqueu_kernel
already has an argument for the invoke function, it is redundant
to have invoke function member in the llvm block literal structure.

This patch removes invoke function from the llvm block literal
structure. It also removes the bitcast of block invoke function
to the "generic block literal type" which is useless for OpenCL.

This will save some space for the kernel argument, and also
eliminate some store instructions.


https://reviews.llvm.org/D43783

Files:
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenCLRuntime.h
  test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl
  test/CodeGenOpenCL/blocks.cl
  test/CodeGenOpenCL/cl20-device-side-enqueue.cl

Index: test/CodeGenOpenCL/cl20-device-side-enqueue.cl
===
--- test/CodeGenOpenCL/cl20-device-side-enqueue.cl
+++ test/CodeGenOpenCL/cl20-device-side-enqueue.cl
@@ -6,27 +6,25 @@
 typedef void (^bl_t)(local void *);
 typedef struct {int a;} ndrange_t;
 
-// COMMON: %struct.__opencl_block_literal_generic = type { i32, i32, i8 addrspace(4)* }
-
 // For a block global variable, first emit the block literal as a global variable, then emit the block variable itself.
-// COMMON: [[BL_GLOBAL:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* [[INV_G:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
-// COMMON: @block_G =  addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
+// COMMON: [[BL_GLOBAL:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32 } { i32 {{[0-9]+}}, i32 {{[0-9]+}} }
+// COMMON: @block_G =  addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32 } addrspace(1)* [[BL_GLOBAL]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
 
 // For anonymous blocks without captures, emit block literals as global variable.
-// COMMON: [[BLG1:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG2:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG3:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG4:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG5:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG6:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG7:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG8:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVG8:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
-// COMMON: [[BLG9:@__block_literal_global[^ ]*]] = internal