[clang] 520a091 - [Clang] Convert some tests to opaque pointers (NFC)

Nikita Popov via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 6 08:02:45 PDT 2023


Author: Nikita Popov
Date: 2023-06-06T17:02:35+02:00
New Revision: 520a091217ac3c300cea7963038d9b266f42eb0c

URL: https://github.com/llvm/llvm-project/commit/520a091217ac3c300cea7963038d9b266f42eb0c
DIFF: https://github.com/llvm/llvm-project/commit/520a091217ac3c300cea7963038d9b266f42eb0c.diff

LOG: [Clang] Convert some tests to opaque pointers (NFC)

Added: 
    

Modified: 
    clang/test/CodeGenObjC/arc-blocks.m
    clang/test/CodeGenObjC/arc-exceptions.m
    clang/test/CodeGenObjC/arc-literals.m
    clang/test/CodeGenObjC/arc-loadweakretained-release.m
    clang/test/CodeGenObjC/arc-precise-lifetime.m
    clang/test/CodeGenObjC/arc-related-result-type.m
    clang/test/CodeGenObjC/arc.m
    clang/test/CodeGenObjC/block-6.m
    clang/test/CodeGenObjC/block-desc-str.m
    clang/test/CodeGenObjC/blocks.m
    clang/test/CodeGenObjC/boxing.m
    clang/test/CodeGenObjC/debug-info-block-line.m
    clang/test/CodeGenObjC/debug-info-blocks.m
    clang/test/CodeGenObjC/direct-method.m
    clang/test/CodeGenObjC/disable-tail-call-escaping-block.m
    clang/test/CodeGenObjC/externally-retained.m
    clang/test/CodeGenObjC/for-in.m
    clang/test/CodeGenObjC/fp2ret.m
    clang/test/CodeGenObjC/fpret.m
    clang/test/CodeGenObjC/fragile-arc.m
    clang/test/CodeGenObjC/mangle-blocks.m
    clang/test/CodeGenObjC/messages-2.m
    clang/test/CodeGenObjC/messages.m
    clang/test/CodeGenObjC/metadata-class-properties.m

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m
index 6f2c9809aa6f5..e5bc6db956eef 100644
--- a/clang/test/CodeGenObjC/arc-blocks.m
+++ b/clang/test/CodeGenObjC/arc-blocks.m
@@ -1,16 +1,15 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-HEAP -check-prefix=CHECK-COMMON %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -fobjc-avoid-heapify-local-blocks -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-NOHEAP -check-prefix=CHECK-COMMON %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT -check-prefix=CHECK-COMMON %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-HEAP -check-prefix=CHECK-COMMON %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -fobjc-avoid-heapify-local-blocks -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-NOHEAP -check-prefix=CHECK-COMMON %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT -check-prefix=CHECK-COMMON %s
 
-// CHECK-COMMON: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
-// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP44:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32s to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i64 256 }, align 8
-// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP9:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32r to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32r to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i64 16 }, align 8
-// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP46:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 48, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32s to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @{{.*}}, i32 0, i32 0) }, align 8
-// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP48:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32b to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @{{.*}}, i32 0, i32 0), i64 256 }, align 8
+// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP44:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, i64 } { i64 0, i64 40, ptr @__copy_helper_block_8_32s, ptr @__destroy_helper_block_8_32s, ptr @{{.*}}, i64 256 }, align 8
+// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP9:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, i64 } { i64 0, i64 40, ptr @__copy_helper_block_8_32r, ptr @__destroy_helper_block_8_32r, ptr @{{.*}}, i64 16 }, align 8
+// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP46:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 48, ptr @__copy_helper_block_8_32s, ptr @__destroy_helper_block_8_32s, ptr @{{.*}}, ptr @{{.*}} }, align 8
+// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP48:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, i64 } { i64 0, i64 40, ptr @__copy_helper_block_8_32b, ptr @__destroy_helper_block_8_32s, ptr @{{.*}}, i64 256 }, align 8
 
 // Check that no copy/dispose helpers are emitted for this block.
 
-// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP10:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8* } { i64 0, i64 40, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @{{.*}}, i32 0, i32 0) }, align 8
+// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP10:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 40, ptr @{{.*}}, ptr @{{.*}} }, align 8
 
 // This shouldn't crash.
 void test0(id (^maker)(void)) {
@@ -18,58 +17,49 @@ void test0(id (^maker)(void)) {
 }
 
 int (^test1(int x))(void) {
-  // CHECK-LABEL:    define{{.*}} i32 ()* @test1(
+  // CHECK-LABEL:    define{{.*}} ptr @test1(
   // CHECK:      [[X:%.*]] = alloca i32,
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK-NEXT: store i32 {{%.*}}, i32* [[X]]
-  // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to i32 ()*
-  // CHECK-NEXT: [[T1:%.*]] = bitcast i32 ()* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]]
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i32 ()*
-  // CHECK-NEXT: [[T4:%.*]] = bitcast i32 ()* [[T3]] to i8*
-  // CHECK-NEXT: [[T5:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T4]]) [[NUW]]
-  // CHECK-NEXT: [[T6:%.*]] = bitcast i8* [[T5]] to i32 ()*
-  // CHECK-NEXT: ret i32 ()* [[T6]]
+  // CHECK-NEXT: store i32 {{%.*}}, ptr [[X]]
+  // CHECK: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[BLOCK]]) [[NUW:#[0-9]+]]
+  // CHECK-NEXT: [[T5:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T2]]) [[NUW]]
+  // CHECK-NEXT: ret ptr [[T5]]
   return ^{ return x; };
 }
 
 void test2(id x) {
 // CHECK-LABEL:    define{{.*}} void @test2(
-// CHECK:      [[X:%.*]] = alloca i8*,
+// CHECK:      [[X:%.*]] = alloca ptr,
 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}})
-// CHECK-NEXT: store i8* [[PARM]], i8** [[X]]
-// CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]],
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]],
-// CHECK-NEXT: bitcast
+// CHECK-NEXT: [[PARM:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}})
+// CHECK-NEXT: store ptr [[PARM]], ptr [[X]]
+// CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]],
+// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[SLOT]],
 // CHECK-NEXT: call void @test2_helper(
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
 // CHECK-NEXT: ret void
   extern void test2_helper(id (^)(void));
   test2_helper(^{ return x; });
 
-// CHECK:    define linkonce_odr hidden void @__copy_helper_block_8_32s(i8* noundef %0, i8* noundef %1) unnamed_addr #{{[0-9]+}} {
-// CHECK:      [[T0:%.*]] = load i8*, i8**
-// CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8**
-// CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[SRC]], i32 0, i32 5
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]]
+// CHECK:    define linkonce_odr hidden void @__copy_helper_block_8_32s(ptr noundef %0, ptr noundef %1) unnamed_addr #{{[0-9]+}} {
+// CHECK:      [[SRC:%.*]] = load ptr, ptr
+// CHECK-NEXT: [[DST:%.*]] = load ptr, ptr
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[SRC]], i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[T0]]
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T1]]) [[NUW]]
 // CHECK-NEXT: ret void
 
 
-// CHECK:    define linkonce_odr hidden void @__destroy_helper_block_8_32s(i8* noundef %0) unnamed_addr #{{[0-9]+}} {
-// CHECK:      [[T0:%.*]] = load i8*, i8**
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
-// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 5
-// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[T2]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]])
+// CHECK:    define linkonce_odr hidden void @__destroy_helper_block_8_32s(ptr noundef %0) unnamed_addr #{{[0-9]+}} {
+// CHECK:      [[T0:%.*]] = load ptr, ptr
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[T0]], i32 0, i32 5
+// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T2]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]])
 // CHECK-NEXT: ret void
 }
 
@@ -78,40 +68,32 @@ void test3(void (^sink)(id*)) {
   sink(&strong);
 
   // CHECK-LABEL:    define{{.*}} void @test3(
-  // CHECK:      [[SINK:%.*]] = alloca void (i8**)*
-  // CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
-  // CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
-  // CHECK-NEXT: bitcast void (i8**)* {{%.*}} to i8*
-  // CHECK-NEXT: call i8* @llvm.objc.retain(
-  // CHECK-NEXT: bitcast i8*
-  // CHECK-NEXT: store void (i8**)* {{%.*}}, void (i8**)** [[SINK]]
-  // CHECK-NEXT: [[STRONGPTR1:%.*]] = bitcast i8** [[STRONG]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[STRONGPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[STRONG]]
-
-  // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]]
-  // CHECK-NEXT: bitcast
+  // CHECK:      [[SINK:%.*]] = alloca ptr
+  // CHECK-NEXT: [[STRONG:%.*]] = alloca ptr
+  // CHECK-NEXT: [[TEMP:%.*]] = alloca ptr
+  // CHECK-NEXT: call ptr @llvm.objc.retain(
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[SINK]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[STRONG]])
+  // CHECK-NEXT: store ptr null, ptr [[STRONG]]
+
+  // CHECK-NEXT: [[BLOCK:%.*]] = load ptr, ptr [[SINK]]
   // CHECK-NEXT: getelementptr
-  // CHECK-NEXT: [[BLOCK:%.*]] = bitcast
-  // CHECK-NEXT: [[V:%.*]] = load i8*, i8** [[STRONG]]
-  // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]]
-  // CHECK-NEXT: [[F0:%.*]] = load i8*, i8**
-  // CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)*
-  // CHECK-NEXT: call void [[F1]](i8* noundef [[BLOCK]], i8** noundef [[TEMP]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]]
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V]]) [[NUW]]
-  // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[STRONG]]
-  // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
-
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[STRONG]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[STRONGPTR2]])
-
-  // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]]
-  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[STRONG]]
+  // CHECK-NEXT: store ptr [[V]], ptr [[TEMP]]
+  // CHECK-NEXT: [[F0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void [[F0]](ptr noundef [[BLOCK]], ptr noundef [[TEMP]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP]]
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[V]]) [[NUW]]
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[STRONG]]
+  // CHECK-NEXT: store ptr [[T1]], ptr [[STRONG]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
+
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[STRONG]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[STRONG]])
+
+  // CHECK-NEXT: load ptr, ptr [[SINK]]
   // CHECK-NEXT: call void @llvm.objc.release
   // CHECK-NEXT: ret void
 
@@ -126,51 +108,48 @@ void test4(void) {
   // CHECK-LABEL:    define{{.*}} void @test4()
   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 2
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 2
   // 0x02000000 - has copy/dispose helpers strong
-  // CHECK-NEXT: store i32 838860800, i32* [[T0]]
-  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
-  // CHECK-NEXT: store i8* [[T0]], i8** [[SLOT]]
-  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
+  // CHECK-NEXT: store i32 838860800, ptr [[T0]]
+  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 6
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @test4_source() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]], ptr [[SLOT]]
+  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 6
   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
   // CHECK:      store i32 -1040187392,
-  // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: store i8* [[T0]], i8**
+  // CHECK: store ptr [[VAR]], ptr
   // CHECK:      call void @test4_helper(
-  // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK: call void @_Block_object_dispose(ptr [[VAR]], i32 8)
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   // CHECK: ret void
 
-  // CHECK-LABEL:    define internal void @__Block_byref_object_copy_(i8* noundef %0, i8* noundef %1) #{{[0-9]+}} {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: load i8*, i8**
-  // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]*
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[T1]]
-  // CHECK-NEXT: store i8* [[T2]], i8** [[T0]]
-  // CHECK-NEXT: store i8* null, i8** [[T1]]
+  // CHECK-LABEL:    define internal void @__Block_byref_object_copy_(ptr noundef %0, ptr noundef %1) #{{[0-9]+}} {
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: load ptr, ptr
+  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[T1]]
+  // CHECK-NEXT: store ptr [[T2]], ptr [[T0]]
+  // CHECK-NEXT: store ptr null, ptr [[T1]]
 
-  // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_(i8* noundef %0) #{{[0-9]+}} {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_(ptr noundef %0) #{{[0-9]+}} {
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
 
   // CHECK-LABEL:    define internal void @__test4_block_invoke
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align 8
-  // CHECK-NEXT: store i8* null, i8** [[SLOT]],
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align 8
+  // CHECK-NEXT: store ptr null, ptr [[SLOT]],
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   // CHECK-NEXT: ret void
 
-  // CHECK-LABEL:    define linkonce_odr hidden void @__copy_helper_block_8_32r(i8* noundef %0, i8* noundef %1) unnamed_addr #{{[0-9]+}} {
-  // CHECK:      call void @_Block_object_assign(i8* {{%.*}}, i8* {{%.*}}, i32 8)
+  // CHECK-LABEL:    define linkonce_odr hidden void @__copy_helper_block_8_32r(ptr noundef %0, ptr noundef %1) unnamed_addr #{{[0-9]+}} {
+  // CHECK:      call void @_Block_object_assign(ptr {{%.*}}, ptr {{%.*}}, i32 8)
 
-  // CHECK-LABEL:    define linkonce_odr hidden void @__destroy_helper_block_8_32r(i8* noundef %0) unnamed_addr #{{[0-9]+}} {
-  // CHECK:      call void @_Block_object_dispose(i8* {{%.*}}, i32 8)
+  // CHECK-LABEL:    define linkonce_odr hidden void @__destroy_helper_block_8_32r(ptr noundef %0) unnamed_addr #{{[0-9]+}} {
+  // CHECK:      call void @_Block_object_dispose(ptr {{%.*}}, i32 8)
 }
 
 void test5(void) {
@@ -180,23 +159,20 @@ void test5(void) {
   test5_helper(^{ (void) var; });
 
   // CHECK-LABEL:    define{{.*}} void @test5()
-  // CHECK:      [[VAR:%.*]] = alloca i8*
+  // CHECK:      [[VAR:%.*]] = alloca ptr
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]])
-  // CHECK: [[T1:%.*]] = call i8* @test5_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[VAR]])
+  // CHECK: [[T1:%.*]] = call ptr @test5_source() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: store ptr [[T1]], ptr [[VAR]],
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   // 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT
-  // CHECK:      store i32 -1073741824, i32*
-  // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[VAR]]
-  // CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]]
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
+  // CHECK:      store i32 -1073741824, ptr
+  // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: store ptr [[T0]], ptr [[CAPTURE]]
   // CHECK: call void @test5_helper
-  // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast i8** [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[VARPTR2]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[VAR]])
   // CHECK-NEXT: ret void
 }
 
@@ -209,45 +185,40 @@ void test6(void) {
   // CHECK-LABEL:    define{{.*}} void @test6()
   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 48, i8* [[VARPTR1]])
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 2
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 48, ptr [[VAR]])
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 2
   // 0x02000000 - has copy/dispose helpers weak
-  // CHECK-NEXT: store i32 1107296256, i32* [[T0]]
-  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @test6_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
+  // CHECK-NEXT: store i32 1107296256, ptr [[T0]]
+  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 6
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @test6_source() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[SLOT]], ptr [[T1]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
+  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[VAR]], i32 0, i32 6
   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
   // CHECK:      store i32 -1040187392,
-  // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP9]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
-  // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: store i8* [[T0]], i8**
+  // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
+// CHECK: store ptr @[[BLOCK_DESCRIPTOR_TMP9]], ptr %[[BLOCK_DESCRIPTOR]], align 8
+  // CHECK: store ptr [[VAR]], ptr
   // CHECK:      call void @test6_helper(
-  // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[SLOT]])
-  // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* [[VARPTR2]])
+  // CHECK: call void @_Block_object_dispose(ptr [[VAR]], i32 8)
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[SLOT]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 48, ptr [[VAR]])
   // CHECK-NEXT: ret void
 
-  // CHECK-LABEL:    define internal void @__Block_byref_object_copy_.{{[0-9]+}}(i8* noundef %0, i8* noundef %1) #{{[0-9]+}} {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: load i8*, i8**
-  // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]*
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[T0]], i8** [[T1]])
+  // CHECK-LABEL:    define internal void @__Block_byref_object_copy_.{{[0-9]+}}(ptr noundef %0, ptr noundef %1) #{{[0-9]+}} {
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: load ptr, ptr
+  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: call void @llvm.objc.moveWeak(ptr [[T0]], ptr [[T1]])
 
-  // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(i8* noundef %0) #{{[0-9]+}} {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]])
+  // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(ptr noundef %0) #{{[0-9]+}} {
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr {{%.*}}, i32 0, i32 6
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[T0]])
 
   // CHECK-LABEL:    define internal void @__test6_block_invoke
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
-  // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[SLOT]], i8* null)
+  // CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[SLOT]], ptr null)
   // CHECK-NEXT: ret void
 }
 
@@ -259,34 +230,34 @@ void test7(void) {
   test7_helper(^{ test7_consume(var); });
 
   // CHECK-LABEL:    define{{.*}} void @test7()
-  // CHECK:      [[VAR:%.*]] = alloca i8*,
+  // CHECK:      [[VAR:%.*]] = alloca ptr,
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK:      [[T1:%.*]] = call i8* @test7_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK:      [[T1:%.*]] = call ptr @test7_source() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[VAR]], ptr [[T1]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
   // CHECK:      store i32 -1040187392,
-  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[SLOT]], i8** [[VAR]])
+  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+  // CHECK-NEXT: call void @llvm.objc.copyWeak(ptr [[SLOT]], ptr [[VAR]])
   // CHECK:      call void @test7_helper(
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** {{%.*}})
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[VAR]])
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr {{%.*}})
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[VAR]])
   // CHECK: ret void
 
   // CHECK-LABEL:    define internal void @__test7_block_invoke
-  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[SLOT]])
-  // CHECK-NEXT: call void @test7_consume(i8* noundef [[T0]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr {{%.*}}, i32 0, i32 5
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[SLOT]])
+  // CHECK-NEXT: call void @test7_consume(ptr noundef [[T0]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   // CHECK: ret void
 
-  // CHECK-LABEL:    define linkonce_odr hidden void @__copy_helper_block_8_32w(i8* noundef %0, i8* noundef %1) unnamed_addr #{{[0-9]+}} {
+  // CHECK-LABEL:    define linkonce_odr hidden void @__copy_helper_block_8_32w(ptr noundef %0, ptr noundef %1) unnamed_addr #{{[0-9]+}} {
   // CHECK:      getelementptr
   // CHECK-NEXT: getelementptr
   // CHECK-NEXT: call void @llvm.objc.copyWeak(
 
-  // CHECK-LABEL:    define linkonce_odr hidden void @__destroy_helper_block_8_32w(i8* noundef %0) unnamed_addr #{{[0-9]+}} {
+  // CHECK-LABEL:    define linkonce_odr hidden void @__destroy_helper_block_8_32w(ptr noundef %0) unnamed_addr #{{[0-9]+}} {
   // CHECK:      getelementptr
   // CHECK-NEXT: call void @llvm.objc.destroyWeak(
 }
@@ -295,18 +266,17 @@ @interface Test8 @end
 @implementation Test8
 - (void) test {
 // CHECK:    define internal void @"\01-[Test8 test]"
-// CHECK:      [[SELF:%.*]] = alloca [[TEST8:%.*]]*,
-// CHECK-NEXT: alloca i8*
+// CHECK:      [[SELF:%.*]] = alloca ptr,
+// CHECK-NEXT: alloca ptr
 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
 // CHECK: store
 // CHECK-NEXT: store
-// CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]*, [[TEST8]]** [[SELF]],
-// CHECK-NEXT: store %0* [[T1]], %0** [[T0]]
-// CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to
+// CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]],
+// CHECK-NEXT: store ptr [[T1]], ptr [[T0]]
 // CHECK: call void @test8_helper(
-// CHECK-NEXT: [[T2:%.*]] = load [[TEST8]]*, [[TEST8]]** [[T0]]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[TEST8]]* [[T2]])
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[T0]]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[T2]])
 // CHECK: ret void
 
   extern void test8_helper(void (^)(void));
@@ -322,16 +292,15 @@ id test9(void) {
       return test9_produce();
   }();
 
-// CHECK-LABEL:    define{{.*}} i8* @test9(
-// CHECK:      load i8*, i8** getelementptr
-// CHECK-NEXT: bitcast i8*
-// CHECK-NEXT: call i8*
-// CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue
-// CHECK-NEXT: ret i8*
+// CHECK-LABEL:    define{{.*}} ptr @test9(
+// CHECK:      load ptr, ptr getelementptr
+// CHECK-NEXT: call ptr
+// CHECK-NEXT: tail call ptr @llvm.objc.autoreleaseReturnValue
+// CHECK-NEXT: ret ptr
 
-// CHECK:      call i8* @test9_produce() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK:      call ptr @test9_produce() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
-// CHECK-NEXT: ret i8*
+// CHECK-NEXT: ret ptr
 }
 
 // rdar://problem/9814099
@@ -341,33 +310,27 @@ void test10a(void) {
   __block void (^block)(void) = ^{ block(); };
   // CHECK-LABEL:       define{{.*}} void @test10a()
   // CHECK:             [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
-  // CHECK-NOHEAP:      [[BLOCK1:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
+  // CHECK-NOHEAP:      [[BLOCK1:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
 
   // Zero-initialization before running the initializer.
-  // CHECK:             [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
-  // CHECK-NEXT:        store void ()* null, void ()** [[T0]], align 8
+  // CHECK:             [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 6
+  // CHECK-NEXT:        store ptr null, ptr [[T0]], align 8
 
   // Run the initializer as an assignment.
-  // CHECK-HEAP:        [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
-  // CHECK-HEAP-NEXT:   [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]])
-  // CHECK-HEAP-NEXT:   [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
-  // CHECK-NOHEAP:      [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK1]] to void ()*
-  // CHECK-NEXT:        [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1
-  // CHECK-NEXT:        [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]]
-  // CHECK-NEXT:        [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6
-  // CHECK-NEXT:        [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8
-  // CHECK-HEAP-NEXT:   store void ()* {{%.*}}, void ()** [[T5]], align 8
-  // CHECK-NOHEAP-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8
-  // CHECK-NEXT:        [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
-  // CHECK-NEXT:        call void @llvm.objc.release(i8* [[T7]])
+  // CHECK-HEAP:   [[T1:%.*]] = call ptr @llvm.objc.retainBlock(ptr {{%.*}})
+  // CHECK:        [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 1
+  // CHECK-NEXT:        [[T4:%.*]] = load ptr, ptr [[T3]]
+  // CHECK-NEXT:        [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[T4]], i32 0, i32 6
+  // CHECK-NEXT:        [[T6:%.*]] = load ptr, ptr [[T5]], align 8
+  // CHECK-HEAP-NEXT:   store ptr {{%.*}}, ptr [[T5]], align 8
+  // CHECK-NOHEAP-NEXT: store ptr [[BLOCK1]], ptr [[T5]], align 8
+  // CHECK-NEXT:        call void @llvm.objc.release(ptr [[T6]])
 
   // Destroy at end of function.
-  // CHECK-NEXT:        [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
-  // CHECK-NEXT:        [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8*
-  // CHECK-NEXT:        call void @_Block_object_dispose(i8* [[T0]], i32 8)
-  // CHECK-NEXT:        [[T1:%.*]] = load void ()*, void ()** [[SLOT]]
-  // CHECK-NEXT:        [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
-  // CHECK-NEXT:        call void @llvm.objc.release(i8* [[T2]])
+  // CHECK-NEXT:        [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 6
+  // CHECK-NEXT:        call void @_Block_object_dispose(ptr [[BYREF]], i32 8)
+  // CHECK-NEXT:        [[T1:%.*]] = load ptr, ptr [[SLOT]]
+  // CHECK-NEXT:        call void @llvm.objc.release(ptr [[T1]])
   // CHECK: ret void
 }
 
@@ -376,27 +339,21 @@ void test10a(void) {
 // We can also use _Block_object_assign/destroy with
 // BLOCK_FIELD_IS_BLOCK as long as we don't pass BLOCK_BYREF_CALLER.
 
-// CHECK-LABEL: define internal void @__Block_byref_object_copy_.{{[0-9]+}}(i8* noundef %0, i8* noundef %1) #{{[0-9]+}} {
-// CHECK:      [[D0:%.*]] = load i8*, i8** {{%.*}}
-// CHECK-NEXT: [[D1:%.*]] = bitcast i8* [[D0]] to [[BYREF_T]]*
-// CHECK-NEXT: [[D2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[D1]], i32 0, i32 6
-// CHECK-NEXT: [[S0:%.*]] = load i8*, i8** {{%.*}}
-// CHECK-NEXT: [[S1:%.*]] = bitcast i8* [[S0]] to [[BYREF_T]]*
-// CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[S1]], i32 0, i32 6
-// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[S2]], align 8
-// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
-// CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8
+// CHECK-LABEL: define internal void @__Block_byref_object_copy_.{{[0-9]+}}(ptr noundef %0, ptr noundef %1) #{{[0-9]+}} {
+// CHECK:      [[D0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[D2:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[D0]], i32 0, i32 6
+// CHECK-NEXT: [[S0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[S0]], i32 0, i32 6
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[S2]], align 8
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[D2]], align 8
 // CHECK: ret void
 
-// CHECK-LABEL: define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(i8* noundef %0) #{{[0-9]+}} {
-// CHECK:      [[T0:%.*]] = load i8*, i8** {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BYREF_T]]*
-// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T1]], i32 0, i32 6
-// CHECK-NEXT: [[T3:%.*]] = load void ()*, void ()** [[T2]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]])
+// CHECK-LABEL: define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(ptr noundef %0) #{{[0-9]+}} {
+// CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[T0]], i32 0, i32 6
+// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T2]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]])
 // CHECK-NEXT: ret void
 
 // Test that we correctly assign to __block variables when the
@@ -407,34 +364,28 @@ void test10b(void) {
 
   // CHECK-LABEL:       define{{.*}} void @test10b()
   // CHECK:             [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
-  // CHECK-NOHEAP:      [[BLOCK3:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
+  // CHECK-NOHEAP:      [[BLOCK3:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
 
   // Zero-initialize.
-  // CHECK:             [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
-  // CHECK-NEXT:        store void ()* null, void ()** [[T0]], align 8
+  // CHECK:             [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 6
+  // CHECK-NEXT:        store ptr null, ptr [[T0]], align 8
 
-  // CHECK-NEXT:        [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
+  // CHECK-NEXT:        [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 6
 
   // The assignment.
-  // CHECK-HEAP:        [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
-  // CHECK-HEAP-NEXT:   [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]])
-  // CHECK-HEAP-NEXT:   [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
-  // CHECK-NOHEAP:      [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK3]] to void ()*
-  // CHECK-NEXT:        [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1
-  // CHECK-NEXT:        [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]]
-  // CHECK-NEXT:        [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6
-  // CHECK-NEXT:        [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8
-  // CHECK-HEAP-NEXT:   store void ()* {{%.*}}, void ()** [[T5]], align 8
-  // CHECK-NOHEAP-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8
-  // CHECK-NEXT:        [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
-  // CHECK-NEXT:        call void @llvm.objc.release(i8* [[T7]])
+  // CHECK-HEAP:   [[T1:%.*]] = call ptr @llvm.objc.retainBlock(ptr {{%.*}})
+  // CHECK:        [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[BYREF]], i32 0, i32 1
+  // CHECK-NEXT:        [[T4:%.*]] = load ptr, ptr [[T3]]
+  // CHECK-NEXT:        [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], ptr [[T4]], i32 0, i32 6
+  // CHECK-NEXT:        [[T6:%.*]] = load ptr, ptr [[T5]], align 8
+  // CHECK-HEAP-NEXT:   store ptr {{%.*}}, ptr [[T5]], align 8
+  // CHECK-NOHEAP-NEXT: store ptr [[BLOCK3]], ptr [[T5]], align 8
+  // CHECK-NEXT:        call void @llvm.objc.release(ptr [[T6]])
 
   // Destroy at end of function.
-  // CHECK-NEXT:        [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8*
-  // CHECK-NEXT:        call void @_Block_object_dispose(i8* [[T0]], i32 8)
-  // CHECK-NEXT:        [[T1:%.*]] = load void ()*, void ()** [[SLOT]]
-  // CHECK-NEXT:        [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
-  // CHECK-NEXT:        call void @llvm.objc.release(i8* [[T2]])
+  // CHECK-NEXT:        call void @_Block_object_dispose(ptr [[BYREF]], i32 8)
+  // CHECK-NEXT:        [[T1:%.*]] = load ptr, ptr [[SLOT]]
+  // CHECK-NEXT:        call void @llvm.objc.release(ptr [[T1]])
   // CHECK: ret void
 }
 
@@ -447,14 +398,9 @@ void test11a(void) {
   // CHECK-LABEL:    define{{.*}} void @test11a()
   // CHECK:      [[X:%.*]] = alloca i32, align 4
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
-  // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
-  // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
-  // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
-  // CHECK-NEXT: call void @test11_helper(i8* noundef [[T4]])
-  // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
+  // CHECK: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[BLOCK]])
+  // CHECK-NEXT: call void @test11_helper(ptr noundef [[T2]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
   // CHECK: ret void
 }
 void test11b(void) {
@@ -463,16 +409,12 @@ void test11b(void) {
 
   // CHECK-LABEL:    define{{.*}} void @test11b()
   // CHECK:      [[X:%.*]] = alloca i32, align 4
-  // CHECK-NEXT: [[B:%.*]] = alloca i8*, align 8
+  // CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
-  // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
-  // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
-  // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
-  // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8
-  // CHECK-NEXT: [[T5:%.*]] = load i8*, i8** [[B]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
+  // CHECK: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[BLOCK]])
+  // CHECK-NEXT: store ptr [[T2]], ptr [[B]], align 8
+  // CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[B]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T5]])
   // CHECK: ret void
 }
 
@@ -483,17 +425,17 @@ @interface Test12
 @end
 @implementation Test12
 @synthesize ablock, nblock;
-// CHECK:    define internal void ()* @"\01-[Test12 ablock]"(
-// CHECK:    call i8* @objc_getProperty(i8* noundef {{%.*}}, i8* noundef {{%.*}}, i64 noundef {{%.*}}, i1 noundef zeroext true)
+// CHECK:    define internal ptr @"\01-[Test12 ablock]"(
+// CHECK:    call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, i1 noundef zeroext true)
 
 // CHECK:    define internal void @"\01-[Test12 setAblock:]"(
-// CHECK:    call void @objc_setProperty(i8* noundef {{%.*}}, i8* noundef {{%.*}}, i64 noundef {{%.*}}, i8* noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
+// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
 
-// CHECK:    define internal void ()* @"\01-[Test12 nblock]"(
-// CHECK:    %add.ptr = getelementptr inbounds i8, i8* %1, i64 %ivar
+// CHECK:    define internal ptr @"\01-[Test12 nblock]"(
+// CHECK:    %add.ptr = getelementptr inbounds i8, ptr %0, i64 %ivar
 
 // CHECK:    define internal void @"\01-[Test12 setNblock:]"(
-// CHECK:    call void @objc_setProperty(i8* noundef {{%.*}}, i8* noundef {{%.*}}, i64 noundef {{%.*}}, i8* noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
+// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
 @end
 
 // rdar://problem/10131784
@@ -505,52 +447,46 @@ void test13(id x) {
   test13_use(b);
 
   // CHECK-LABEL:    define{{.*}} void @test13(
-  // CHECK:      [[X:%.*]] = alloca i8*, align 8
-  // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8
+  // CHECK:      [[X:%.*]] = alloca ptr, align 8
+  // CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
   // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
-  // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca i8**,
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}})
-  // CHECK-NEXT: store i8* [[T0]], i8** [[X]], align 8
-  // CHECK-NEXT: [[BPTR1:%.*]] = bitcast void ()** [[B]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[BPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8
-  // CHECK-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null
-  // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]]
+  // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca ptr,
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}})
+  // CHECK-NEXT: store ptr [[T0]], ptr [[X]], align 8
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[B]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]], align 8
+  // CHECK-NEXT: [[T1:%.*]] = icmp ne ptr [[T0]], null
+  // CHECK-NEXT: store i1 false, ptr [[CLEANUP_ACTIVE]]
   // CHECK-NEXT: br i1 [[T1]],
 
   // CHECK-NOT:  br
-  // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-  // CHECK-NEXT: store i8* [[T1]], i8** [[CAPTURE]], align 8
-  // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
-  // CHECK-NEXT: store i8** [[CAPTURE]], i8*** [[COND_CLEANUP_SAVE]], align 8
-  // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
+  // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]], align 8
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T1]], ptr [[CAPTURE]], align 8
+  // CHECK-NEXT: store i1 true, ptr [[CLEANUP_ACTIVE]]
+  // CHECK-NEXT: store ptr [[CAPTURE]], ptr [[COND_CLEANUP_SAVE]], align 8
   // CHECK-NEXT: br label
   // CHECK:      br label
-  // CHECK:      [[T0:%.*]] = phi void ()*
-  // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
-  // CHECK-NEXT: store void ()* [[T3]], void ()** [[B]], align 8
-  // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]], align 8
-  // CHECK-NEXT: call void @test13_use(void ()* noundef [[T0]])
-  // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-
-  // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]]
+  // CHECK:      [[T0:%.*]] = phi ptr
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T2]], ptr [[B]], align 8
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[B]], align 8
+  // CHECK-NEXT: call void @test13_use(ptr noundef [[T0]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[B]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+
+  // CHECK-NEXT: [[T0:%.*]] = load i1, ptr [[CLEANUP_ACTIVE]]
   // CHECK-NEXT: br i1 [[T0]]
-  // CHECK:      [[V12:%.*]] = load i8**, i8*** [[COND_CLEANUP_SAVE]], align 8
-  // CHECK:      [[T0:%.*]] = load i8*, i8** [[V12]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK:      [[V12:%.*]] = load ptr, ptr [[COND_CLEANUP_SAVE]], align 8
+  // CHECK:      [[T0:%.*]] = load ptr, ptr [[V12]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   // CHECK-NEXT: br label
 
-  // CHECK:      [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[BPTR2]])
-  // CHECK-NEXT:      [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr [[B]])
+  // CHECK-NEXT:      [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   // CHECK-NEXT: ret void
 }
 
@@ -571,11 +507,10 @@ void test16(void) {
   void (^BLKVAR)(void) = ^{ BLKVAR(); };
 
   // CHECK-LABEL: define{{.*}} void @test16(
-  // CHECK: [[BLKVAR:%.*]]  = alloca void ()*, align 8
+  // CHECK: [[BLKVAR:%.*]]  = alloca ptr, align 8
   // CHECK-NEXT:  [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK-NEXT:  [[BLKVARPTR1:%.*]] = bitcast void ()** [[BLKVAR]] to i8*
-  // CHECK-NEXT:  call void @llvm.lifetime.start.p0i8(i64 8, i8* [[BLKVARPTR1]])
-  // CHECK-NEXT:  store void ()* null, void ()** [[BLKVAR]], align 8
+  // CHECK-NEXT:  call void @llvm.lifetime.start.p0(i64 8, ptr [[BLKVAR]])
+  // CHECK-NEXT:  store ptr null, ptr [[BLKVAR]], align 8
 }
 
 // rdar://12151005
@@ -591,60 +526,53 @@ void test16(void) {
   }
   return (void*) 0;
 }
-// CHECK-LABEL:    define{{.*}} i8* ()* @test17(
-// CHECK:      [[RET:%.*]] = alloca i8* ()*, align
-// CHECK-NEXT: [[SELF:%.*]] = alloca i8*,
+// CHECK-LABEL:    define{{.*}} ptr @test17(
+// CHECK:      [[RET:%.*]] = alloca ptr, align
+// CHECK-NEXT: [[SELF:%.*]] = alloca ptr,
 // CHECK:      [[B0:%.*]] = alloca [[BLOCK:<.*>]], align
 // CHECK:      [[B1:%.*]] = alloca [[BLOCK]], align
-// CHECK:      [[T0:%.*]] = call i8* @llvm.objc.retain(i8*
-// CHECK-NEXT: store i8* [[T0]], i8** [[SELF]], align
+// CHECK:      [[T0:%.*]] = call ptr @llvm.objc.retain(ptr
+// CHECK-NEXT: store ptr [[T0]], ptr [[SELF]], align
 // CHECK-NOT:  objc_retain
 // CHECK-NOT:  objc_release
-// CHECK:      [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B0]], i32 0, i32 5
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: store i8* [[T2]], i8** [[CAPTURED]],
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B0]] to i8* ()*
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()*
-// CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]]
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CAPTURED]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+// CHECK:      [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], ptr [[B0]], i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]], align
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T1]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[CAPTURED]],
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[B0]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[RET]]
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[CAPTURED]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
 // CHECK-NEXT: store i32
 // CHECK-NEXT: br label
 // CHECK-NOT:  objc_retain
 // CHECK-NOT:  objc_release
-// CHECK:      [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B1]], i32 0, i32 5
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: store i8* [[T2]], i8** [[CAPTURED]],
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B1]] to i8* ()*
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()*
-// CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]]
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CAPTURED]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+// CHECK:      [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], ptr [[B1]], i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]], align
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T1]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[CAPTURED]],
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[B1]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[RET]]
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[CAPTURED]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
 // CHECK-NEXT: store i32
 // CHECK-NEXT: br label
 
 void test18(id x) {
 // CHECK-UNOPT-LABEL:    define{{.*}} void @test18(
-// CHECK-UNOPT:      [[X:%.*]] = alloca i8*,
+// CHECK-UNOPT:      [[X:%.*]] = alloca ptr,
 // CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-UNOPT-NEXT: store i8* null, i8** [[X]]
-// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], 
-// CHECK-UNOPT: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 4
-// CHECK-UNOPT: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP44]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
-// CHECK-UNOPT:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8*, i8** [[X]],
-// CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-// CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]],
-// CHECK-UNOPT-NEXT: bitcast
+// CHECK-UNOPT-NEXT: store ptr null, ptr [[X]]
+// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], 
+// CHECK-UNOPT: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 4
+// CHECK-UNOPT: store ptr @[[BLOCK_DESCRIPTOR_TMP44]], ptr %[[BLOCK_DESCRIPTOR]], align 8
+// CHECK-UNOPT:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT-NEXT: [[T0:%.*]] = load ptr, ptr [[X]],
+// CHECK-UNOPT-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-UNOPT-NEXT: store ptr [[T1]], ptr [[SLOT]],
 // CHECK-UNOPT-NEXT: call void @test18_helper(
-// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[SLOT]], i8* null) [[NUW:#[0-9]+]]
-// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) [[NUW]]
+// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(ptr [[SLOT]], ptr null) [[NUW:#[0-9]+]]
+// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null) [[NUW]]
 // CHECK-UNOPT-NEXT: ret void
   extern void test18_helper(id (^)(void));
   test18_helper(^{ return x; });
@@ -658,8 +586,8 @@ void testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(id x, id y) {
 }
 
 // CHECK-LABEL: define{{.*}} void @testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers
-// %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8* }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR_TMP46]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
+// %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
+// CHECK: store ptr @[[BLOCK_DESCRIPTOR_TMP46]], ptr %[[BLOCK_DESCRIPTOR]], align 8
 
 // CHECK-LABEL: define internal void @__testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke
 // CHECK-UNOPT-LABEL: define internal void @__testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke
@@ -669,63 +597,56 @@ void testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(id x, id y) {
 void test19(void (^b)(void)) {
 // CHECK-LABEL:    define{{.*}} void @test19(
 //   Prologue.
-// CHECK:      [[B:%.*]] = alloca void ()*,
+// CHECK:      [[B:%.*]] = alloca ptr,
 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
-// CHECK-NEXT: store void ()* [[T2]], void ()** [[B]]
+// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}})
+// CHECK-NEXT: store ptr [[T1]], ptr [[B]]
 
 //   Block setup.  We skip most of this.  Note the bare retain.
-// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP48]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
-// CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]],
-// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
-// CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]],
+// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 4
+// CHECK: store ptr @[[BLOCK_DESCRIPTOR_TMP48]], ptr %[[BLOCK_DESCRIPTOR]], align 8
+// CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[B]],
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[SLOT]],
 //   Call.
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void (i32)*
-// CHECK-NEXT: call void @test19_sink(void (i32)* noundef [[T0]])
+// CHECK-NEXT: call void @test19_sink(ptr noundef [[BLOCK]])
 
   test19_sink(^(int x) { b(); });
 
 //   Block teardown.
-// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[SLOT]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
 
 //   Local cleanup.
-// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[B]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
 
 // CHECK-NEXT: ret void
 }
 
 // CHECK-LABEL: define{{.*}} void @test20(
-// CHECK: [[XADDR:%.*]] = alloca i8*
+// CHECK: [[XADDR:%.*]] = alloca ptr
 // CHECK-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]>
-// CHECK-NEXT: [[RETAINEDX:%.*]] = call i8* @llvm.objc.retain(i8* %{{.*}})
-// CHECK-NEXT: store i8* [[RETAINEDX]], i8** [[XADDR]]
-// CHECK: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5
-// CHECK: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]]
-// CHECK: store i8* [[CAPTURED]], i8** [[BLOCKCAPTURED]]
-// CHECK: [[CAPTURE:%.*]] = load i8*, i8** [[BLOCKCAPTURED]]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]])
-// CHECK-NEXT: [[X:%.*]] = load i8*, i8** [[XADDR]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[X]])
+// CHECK-NEXT: [[RETAINEDX:%.*]] = call ptr @llvm.objc.retain(ptr %{{.*}})
+// CHECK-NEXT: store ptr [[RETAINEDX]], ptr [[XADDR]]
+// CHECK: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, ptr [[BLOCK]], i32 0, i32 5
+// CHECK: [[CAPTURED:%.*]] = load ptr, ptr [[XADDR]]
+// CHECK: store ptr [[CAPTURED]], ptr [[BLOCKCAPTURED]]
+// CHECK: [[CAPTURE:%.*]] = load ptr, ptr [[BLOCKCAPTURED]]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[CAPTURE]])
+// CHECK-NEXT: [[X:%.*]] = load ptr, ptr [[XADDR]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[X]])
 // CHECK-NEXT: ret void
 
 // CHECK-UNOPT-LABEL: define{{.*}} void @test20(
-// CHECK-UNOPT: [[XADDR:%.*]] = alloca i8*
+// CHECK-UNOPT: [[XADDR:%.*]] = alloca ptr
 // CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]>
-// CHECK-UNOPT: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5
-// CHECK-UNOPT: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]]
-// CHECK-UNOPT: [[RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[CAPTURED]])
-// CHECK-UNOPT: store i8* [[RETAINED]], i8** [[BLOCKCAPTURED]]
-// CHECK-UNOPT: call void @llvm.objc.storeStrong(i8** [[BLOCKCAPTURED]], i8* null)
+// CHECK-UNOPT: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, ptr [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT: [[CAPTURED:%.*]] = load ptr, ptr [[XADDR]]
+// CHECK-UNOPT: [[RETAINED:%.*]] = call ptr @llvm.objc.retain(ptr [[CAPTURED]])
+// CHECK-UNOPT: store ptr [[RETAINED]], ptr [[BLOCKCAPTURED]]
+// CHECK-UNOPT: call void @llvm.objc.storeStrong(ptr [[BLOCKCAPTURED]], ptr null)
 
 void test20_callee(void (^)(void));
 void test20(const id x) {
@@ -733,9 +654,8 @@ void test20(const id x) {
 }
 
 // CHECK-LABEL: define{{.*}} void @test21(
-// CHECK: %[[V6:.*]] = call i8* @llvm.objc.retainBlock(
-// CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to void ()*
-// CHECK: call void (i32, ...) @test21_callee(i32 noundef 1, void ()* noundef %[[V7]]),
+// CHECK: %[[V6:.*]] = call ptr @llvm.objc.retainBlock(
+// CHECK: call void (i32, ...) @test21_callee(i32 noundef 1, ptr noundef %[[V6]]),
 
 void test21_callee(int n, ...);
 void test21(id x) {
@@ -745,14 +665,14 @@ void test21(id x) {
 // The lifetime of 'x', which is captured by the block in the statement
 // expression, should be extended.
 
-// CHECK-COMMON-LABEL: define{{.*}} i8* @test22(
-// CHECK-COMMON: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, i8* }>, <{ i8*, i32, i32, i8*, %{{.*}}*, i8* }>* %{{.*}}, i32 0, i32 5
-// CHECK-COMMON: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %{{.*}})
-// CHECK-COMMON: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED]], align 8
+// CHECK-COMMON-LABEL: define{{.*}} ptr @test22(
+// CHECK-COMMON: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 5
+// CHECK-COMMON: %[[V3:.*]] = call ptr @llvm.objc.retain(ptr %{{.*}})
+// CHECK-COMMON: store ptr %[[V3]], ptr %[[BLOCK_CAPTURED]], align 8
 // CHECK-COMMON: call void @test22_1()
-// CHECK-UNOPT: call void @llvm.objc.storeStrong(i8** %[[BLOCK_CAPTURED]], i8* null)
-// CHECK: %[[V15:.*]] = load i8*, i8** %[[BLOCK_CAPTURED]], align 8
-// CHECK: call void @llvm.objc.release(i8* %[[V15]])
+// CHECK-UNOPT: call void @llvm.objc.storeStrong(ptr %[[BLOCK_CAPTURED]], ptr null)
+// CHECK: %[[V15:.*]] = load ptr, ptr %[[BLOCK_CAPTURED]], align 8
+// CHECK: call void @llvm.objc.release(ptr %[[V15]])
 
 id test22(int c, id x) {
   extern id test22_0(void);
@@ -765,17 +685,16 @@ -(void)m:(int)i, ...;
 @end
 
 // CHECK-COMMON-LABEL: define{{.*}} void @test23(
-// CHECK-COMMON: %[[V9:.*]] = call i8* @llvm.objc.retainBlock(
-// CHECK-COMMON: %[[V10:.*]] = bitcast i8* %[[V9]] to void ()*
-// CHECK-COMMON: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)(i8* noundef %{{.*}}, i8* noundef %{{.*}}, i32 noundef 123, void ()* noundef %[[V10]])
+// CHECK-COMMON: %[[V9:.*]] = call ptr @llvm.objc.retainBlock(
+// CHECK-COMMON: call void (ptr, ptr, i32, ...) @objc_msgSend(ptr noundef %{{.*}}, ptr noundef %{{.*}}, i32 noundef 123, ptr noundef %[[V9]])
 
 void test23(id x, Test23 *t) {
   [t m:123, ^{ (void)x; }];
 }
 
 // CHECK-COMMON-LABEL: define internal void @"\01+[Test24 m]"(
-// CHECK-COMMON: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8* }* @[[BLOCK_DESCRIPTOR_TMP10]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]],
+// CHECK-COMMON: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
+// CHECK: store ptr @[[BLOCK_DESCRIPTOR_TMP10]], ptr %[[BLOCK_DESCRIPTOR]],
 
 @interface Test24
 @property (class) void (^block)(void);

diff  --git a/clang/test/CodeGenObjC/arc-exceptions.m b/clang/test/CodeGenObjC/arc-exceptions.m
index ec23717c2afc8..e97d1e05f5873 100644
--- a/clang/test/CodeGenObjC/arc-exceptions.m
+++ b/clang/test/CodeGenObjC/arc-exceptions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-runtime-has-weak -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-runtime-has-weak -o - %s | FileCheck %s
 
 @class Ety;
 
@@ -12,16 +12,12 @@ void test0(void) {
   }
 }
 // CHECK-LABEL: define{{.*}} void @test0()
-// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
-// CHECK-NEXT: invoke void @test0_helper()
-// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW:#[0-9]+]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
-// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]]
+// CHECK:      [[E:%e]] = alloca ptr, align 8
+// CHECK:      invoke void @test0_helper()
+// CHECK:      [[T0:%.*]] = call ptr @objc_begin_catch(
+// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW:#[0-9]+]]
+// CHECK-NEXT: store ptr [[T3]], ptr [[E]]
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[E]], ptr null) [[NUW]]
 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
 
 void test1_helper(void);
@@ -32,15 +28,11 @@ void test1(void) {
   }
 }
 // CHECK-LABEL: define{{.*}} void @test1()
-// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
-// CHECK-NEXT: invoke void @test1_helper()
-// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]]
+// CHECK:      [[E:%e]] = alloca ptr, align 8
+// CHECK:      invoke void @test1_helper()
+// CHECK:      [[T0:%.*]] = call ptr @objc_begin_catch(
+// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[E]], ptr [[T0]]) [[NUW]]
+// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[E]]) [[NUW]]
 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
 
 // CHECK: attributes [[NUW]] = { nounwind }

diff  --git a/clang/test/CodeGenObjC/arc-literals.m b/clang/test/CodeGenObjC/arc-literals.m
index 1eec7665178e6..1ac0c76d511d4 100644
--- a/clang/test/CodeGenObjC/arc-literals.m
+++ b/clang/test/CodeGenObjC/arc-literals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -no-enable-noundef-analysis -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -no-enable-noundef-analysis -o - %s | FileCheck %s
 
 #include "literal-support.h"
 
@@ -35,27 +35,25 @@ void test_numeric(void) {
 
 // CHECK-LABEL: define{{.*}} void @test_array
 void test_array(id a, id b) {
-  // CHECK: [[A:%.*]] = alloca i8*,
-  // CHECK: [[B:%.*]] = alloca i8*,
+  // CHECK: [[A:%.*]] = alloca ptr,
+  // CHECK: [[B:%.*]] = alloca ptr,
 
   // Retaining parameters
-  // CHECK: call i8* @llvm.objc.retain(i8*
-  // CHECK: call i8* @llvm.objc.retain(i8*
+  // CHECK: call ptr @llvm.objc.retain(ptr
+  // CHECK: call ptr @llvm.objc.retain(ptr
 
   // Constructing the array
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
-  // CHECK-NEXT: [[V0:%.*]] = load i8*, i8** [[A]],
-  // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
-  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
-  // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[B]],
-  // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
-
-  // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]*, [[CLASS_T:%.*]]** @"OBJC_CLASSLIST
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
-  // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]])
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
+  // CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[A]],
+  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
+  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
+  // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[B]],
+  // CHECK-NEXT: store ptr [[V1]], ptr [[T0]]
+
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
+  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], i64 2) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]], ptr [[V1]])
   id arr = @[a, b];
 
   // CHECK: call void @llvm.objc.release
@@ -66,40 +64,37 @@ void test_array(id a, id b) {
 
 // CHECK-LABEL: define{{.*}} void @test_dictionary
 void test_dictionary(id k1, id o1, id k2, id o2) {
-  // CHECK: [[K1:%.*]] = alloca i8*,
-  // CHECK: [[O1:%.*]] = alloca i8*,
-  // CHECK: [[K2:%.*]] = alloca i8*,
-  // CHECK: [[O2:%.*]] = alloca i8*,
+  // CHECK: [[K1:%.*]] = alloca ptr,
+  // CHECK: [[O1:%.*]] = alloca ptr,
+  // CHECK: [[K2:%.*]] = alloca ptr,
+  // CHECK: [[O2:%.*]] = alloca ptr,
 
   // Retaining parameters
-  // CHECK: call i8* @llvm.objc.retain(i8*
-  // CHECK: call i8* @llvm.objc.retain(i8*
-  // CHECK: call i8* @llvm.objc.retain(i8*
-  // CHECK: call i8* @llvm.objc.retain(i8*
+  // CHECK: call ptr @llvm.objc.retain(ptr
+  // CHECK: call ptr @llvm.objc.retain(ptr
+  // CHECK: call ptr @llvm.objc.retain(ptr
+  // CHECK: call ptr @llvm.objc.retain(ptr
 
   // Constructing the arrays
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i64 0, i64 0
-  // CHECK-NEXT: [[V0:%.*]] = load i8*, i8** [[K1]],
-  // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
-  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
-  // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[O1]],
-  // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
-  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[KEYS]], i64 0, i64 1
-  // CHECK-NEXT: [[V2:%.*]] = load i8*, i8** [[K2]],
-  // CHECK-NEXT: store i8* [[V2]], i8** [[T0]]
-  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
-  // CHECK-NEXT: [[V3:%.*]] = load i8*, i8** [[O2]],
-  // CHECK-NEXT: store i8* [[V3]], i8** [[T0]]
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[KEYS:%[A-Za-z0-9]+]], i64 0, i64 0
+  // CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[K1]],
+  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
+  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
+  // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[O1]],
+  // CHECK-NEXT: store ptr [[V1]], ptr [[T0]]
+  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[KEYS]], i64 0, i64 1
+  // CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[K2]],
+  // CHECK-NEXT: store ptr [[V2]], ptr [[T0]]
+  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
+  // CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[O2]],
+  // CHECK-NEXT: store ptr [[V3]], ptr [[T0]]
 
   // Constructing the dictionary
-  // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]*, [[CLASS_T:%.*]]** @"OBJC_CLASSLIST
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
-  // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
-  // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]])
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
+  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
+  // CHECK-NEXT: [[T4:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], ptr [[KEYS]], i64 2) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T4]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]], ptr [[V1]], ptr [[V2]], ptr [[V3]])
 
   id dict = @{ k1 : o1, k2 : o2 };
 
@@ -121,36 +116,29 @@ @interface B
 // CHECK-LABEL: define{{.*}} void @test_property
 void test_property(B *b) {
   // Retain parameter
-  // CHECK: call i8* @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
 
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[OBJECTS:%.*]], i64 0, i64 0
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[OBJECTS:%.*]], i64 0, i64 0
 
   // Invoke 'prop'
-  // CHECK:      [[T1:%.*]] = bitcast
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
-  // CHECK-NEXT: [[V0:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[B]]* [[V0]])
-  // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
+  // CHECK:      [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
+  // CHECK-NEXT: [[V0:%.*]] = call ptr @objc_msgSend(ptr {{.*}}, ptr [[SEL]]) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[V0]])
 
   // Store to array.
-  // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
+  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
 
   // Invoke arrayWithObjects:count:
-  // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T]]*, [[CLASS_T]]** @"OBJC_CLASSLIST
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
-  // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T3]])
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V1]])
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
+  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], i64 1) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T3]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]])
   // CHECK-NEXT: store
   id arr = @[ b.prop ];
 
   // Release b.prop
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[V0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[V0]])
 
   // Destroy arr
   // CHECK: call void @llvm.objc.release

diff  --git a/clang/test/CodeGenObjC/arc-loadweakretained-release.m b/clang/test/CodeGenObjC/arc-loadweakretained-release.m
index 2ed863a560b79..88e882cdb1ef3 100644
--- a/clang/test/CodeGenObjC/arc-loadweakretained-release.m
+++ b/clang/test/CodeGenObjC/arc-loadweakretained-release.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s
 // rdar://10849570
 
 @interface NSObject @end
@@ -28,13 +28,10 @@ int main (int argc, const char * argv[]) {
     }
 }
 
-// CHECK: [[SIXTEEN:%.*]]  = call i8* @llvm.objc.loadWeakRetained(i8** {{%.*}})
-// CHECK-NEXT:  [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}}
-// CHECK-NEXT:  [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
-// CHECK-NEXT:  [[EIGHTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
-// CHECK-NEXT:  call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:  [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
-// CHECK-NEXT:  call void @llvm.objc.release(i8* [[TWENTY]])
+// CHECK: [[SIXTEEN:%.*]]  = call ptr @llvm.objc.loadWeakRetained(ptr {{%.*}})
+// CHECK-NEXT:  [[EIGHTEEN:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.6
+// CHECK-NEXT:  call void @objc_msgSend
+// CHECK-NEXT:  call void @llvm.objc.release(ptr [[SIXTEEN]])
 
 void test1(int cond) {
   extern void test34_sink(id *);
@@ -44,34 +41,34 @@ void test1(int cond) {
 
 // CHECK-LABEL: define{{.*}} void @test1(
 // CHECK: [[CONDADDR:%.*]] = alloca i32
-// CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
-// CHECK-NEXT: [[INCRTEMP:%.*]] = alloca i8*
-// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
+// CHECK-NEXT: [[WEAK:%.*]] = alloca ptr
+// CHECK-NEXT: [[INCRTEMP:%.*]] = alloca ptr
+// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca ptr
 // CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
 // CHECK-NEXT: store i32
-// CHECK-NEXT: store i8* null, i8** [[WEAK]]
-// CHECK:  [[COND1:%.*]] = phi i8**
-// CHECK-NEXT: [[ICRISNULL:%.*]] = icmp eq i8** [[COND1]], null
-// CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], i8** null, i8** [[INCRTEMP]]
-// CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
+// CHECK-NEXT: store ptr null, ptr [[WEAK]]
+// CHECK:  [[COND1:%.*]] = phi ptr
+// CHECK-NEXT: [[ICRISNULL:%.*]] = icmp eq ptr [[COND1]], null
+// CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], ptr null, ptr [[INCRTEMP]]
+// CHECK-NEXT: store i1 false, ptr [[CONDCLEANUP]]
 // CHECK-NEXT: br i1 [[ICRISNULL]], label [[ICRCONT:%.*]], label [[ICRCOPY:%.*]]
-// CHECK:  [[ONE:%.*]] = call i8* @llvm.objc.loadWeakRetained(
-// CHECK-NEXT: store i8* [[ONE]], i8** [[CONDCLEANUPSAVE]]
-// CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
-// CHECK-NEXT: store i8* [[ONE]], i8** [[INCRTEMP]]
+// CHECK:  [[ONE:%.*]] = call ptr @llvm.objc.loadWeakRetained(
+// CHECK-NEXT: store ptr [[ONE]], ptr [[CONDCLEANUPSAVE]]
+// CHECK-NEXT: store i1 true, ptr [[CONDCLEANUP]]
+// CHECK-NEXT: store ptr [[ONE]], ptr [[INCRTEMP]]
 // CHECK-NEXT: br label
 
 // CHECK: call void @test34_sink(
-// CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq i8** [[COND1]], null
+// CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq ptr [[COND1]], null
 // CHECK-NEXT: br i1 [[ICRISNULL1]], label [[ICRDONE:%.*]], label [[ICRWRITEBACK:%.*]]
-// CHECK:  [[TWO:%.*]] = load i8*, i8** [[INCRTEMP]]
-// CHECK-NEXT:  [[THREE:%.*]] = call i8* @llvm.objc.storeWeak(
+// CHECK:  [[TWO:%.*]] = load ptr, ptr [[INCRTEMP]]
+// CHECK-NEXT:  [[THREE:%.*]] = call ptr @llvm.objc.storeWeak(
 // CHECK-NEXT:  br label [[ICRDONE]]
-// CHECK:  [[CLEANUPISACTIVE:%.*]] = load i1, i1* [[CONDCLEANUP]]
+// CHECK:  [[CLEANUPISACTIVE:%.*]] = load i1, ptr [[CONDCLEANUP]]
 // CHECK-NEXT:  br i1 [[CLEANUPISACTIVE]], label [[CLEASNUPACTION:%.*]], label [[CLEANUPDONE:%.*]]
 
-// CHECK: [[FOUR:%.*]] = load i8*, i8** [[CONDCLEANUPSAVE]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[FOUR]])
+// CHECK: [[FOUR:%.*]] = load ptr, ptr [[CONDCLEANUPSAVE]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[FOUR]])
 // CHECK-NEXT:  br label
-// CHECK:  call void @llvm.objc.destroyWeak(i8** [[WEAK]])
+// CHECK:  call void @llvm.objc.destroyWeak(ptr [[WEAK]])
 // CHECK-NEXT: ret void

diff  --git a/clang/test/CodeGenObjC/arc-precise-lifetime.m b/clang/test/CodeGenObjC/arc-precise-lifetime.m
index 8a44ca42c56a1..988fe5a4caae7 100644
--- a/clang/test/CodeGenObjC/arc-precise-lifetime.m
+++ b/clang/test/CodeGenObjC/arc-precise-lifetime.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
 
@@ -6,23 +6,21 @@
 void test0(void) {
   PRECISE_LIFETIME id x = test0_helper();
   x = 0;
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()
-  // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[CALL:%.*]] = call ptr @test0_helper()
+  // CHECK-NEXT: store ptr [[CALL]], ptr [[X]]
 
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: store i8* null, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW:#[0-9]+]]
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]]) [[NUW:#[0-9]+]]
   // CHECK-NOT:  clang.imprecise_release
 
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW:#[0-9]+]]
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]]) [[NUW:#[0-9]+]]
   // CHECK-NOT:  clang.imprecise_release
 
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -37,30 +35,22 @@ - (char*) interior __attribute__((objc_returns_inner_pointer));
 
 // CHECK-LABEL: define{{.*}} void @test1a_message()
 void test1a_message(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[C:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T6]], i8**
-  // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[C:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainAutorelease(ptr [[T0]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T6:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T6]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   Test1 *ptr = test1_helper();
   char *c = [(ptr) interior];
@@ -69,30 +59,22 @@ void test1a_message(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1a_property()
 void test1a_property(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[C:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T6]], i8**
-  // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[C:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainAutorelease(ptr [[T0]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T6:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T6]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   Test1 *ptr = test1_helper();
   char *c = ptr.interior;
@@ -101,28 +83,22 @@ void test1a_property(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1b_message()
 void test1b_message(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[C:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T3]], i8**
-  // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]]
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[C:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T3:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T3]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
   // CHECK-NOT:  clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   PRECISE_LIFETIME Test1 *ptr = test1_helper();
   char *c = [ptr interior];
@@ -130,28 +106,22 @@ void test1b_message(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1b_property()
 void test1b_property(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[C:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T3]], i8**
-  // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]]
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[C:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T3:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T3]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[C]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
   // CHECK-NOT:  clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   PRECISE_LIFETIME Test1 *ptr = test1_helper();
   char *c = ptr.interior;
@@ -159,30 +129,22 @@ void test1b_property(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1c_message()
 void test1c_message(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[PC:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T6]], i8**
-  // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[PC:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainAutorelease(ptr [[T0]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T6:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T6]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   Test1 *ptr = test1_helper();
   char *pc = [ptr PropertyReturnsInnerPointer];
@@ -190,30 +152,22 @@ void test1c_message(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1c_property()
 void test1c_property(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[PC:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
-  // CHECK-NEXT: store i8* [[T6]], i8**
-  // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[PC:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retainAutorelease(ptr [[T0]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T6:%.*]] = call ptr
+  // CHECK-NEXT: store ptr [[T6]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   Test1 *ptr = test1_helper();
   char *pc = ptr.PropertyReturnsInnerPointer;
@@ -221,27 +175,21 @@ void test1c_property(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1d_message()
 void test1d_message(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[PC:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEL]])
-  // CHECK-NEXT: store i8* [[CALL1]], i8**
-  // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
-  // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TEN]])
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[PC:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[CALL1:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])
+  // CHECK-NEXT: store ptr [[CALL1]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[NINE:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[NINE]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   PRECISE_LIFETIME Test1 *ptr = test1_helper();
   char *pc = [ptr PropertyReturnsInnerPointer];
@@ -249,27 +197,21 @@ void test1d_message(void) {
 
 // CHECK-LABEL: define{{.*}} void @test1d_property()
 void test1d_property(void) {
-  // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
-  // CHECK:      [[PC:%.*]] = alloca i8*, align 8
-  // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK:      call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
-  // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
-  // CHECK-NEXT: store [[TEST1]]* [[T0]]
-  // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
-  // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEL]])
-  // CHECK-NEXT: store i8* [[CALL1]], i8**
-  // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
-  // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**
-  // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TEN]])
-  // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTRPTR2]])
+  // CHECK:      [[PTR:%.*]] = alloca ptr, align 8
+  // CHECK:      [[PC:%.*]] = alloca ptr, align 8
+  // CHECK:      call void @llvm.lifetime.start.p0(i64 8, ptr [[PTR]])
+  // CHECK:      [[T0:%.*]] = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T0]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
+  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[CALL1:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])
+  // CHECK-NEXT: store ptr [[CALL1]], ptr
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PC]])
+  // CHECK-NEXT: [[NINE:%.*]] = load ptr, ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[NINE]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[PTR]])
   // CHECK-NEXT: ret void
   PRECISE_LIFETIME Test1 *ptr = test1_helper();
   char *pc = ptr.PropertyReturnsInnerPointer;
@@ -283,37 +225,32 @@ @interface Test2 {
 // CHECK-LABEL:      define{{.*}} void @test2(
 void test2(Test2 *x) {
   x->ivar = 0;
-  // CHECK:      [[X:%.*]] = alloca [[TEST2:%.*]]*
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) [[NUW]]
-  // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]*
-  // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]],
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}}) [[NUW]]
+  // CHECK-NEXT: store ptr [[T1]], ptr [[X]],
 
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]],
-  // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test2.ivar"
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 [[OFFSET]]
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]],
-  // CHECK-NEXT: store i8* null, i8** [[T3]],
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) [[NUW]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]],
+  // CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2.ivar"
+  // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[OFFSET]]
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[T2]],
+  // CHECK-NEXT: store ptr null, ptr [[T2]],
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]]) [[NUW]]
   // CHECK-NOT:  imprecise
 
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
 
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL:      define{{.*}} void @test3(i8*
+// CHECK-LABEL:      define{{.*}} void @test3(ptr
 void test3(PRECISE_LIFETIME id x) {
-  // CHECK:      [[X:%.*]] = alloca i8*,
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) [[NUW]]
-  // CHECK-NEXT: store i8* [[T0]], i8** [[X]],
+  // CHECK:      [[X:%.*]] = alloca ptr,
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}}) [[NUW]]
+  // CHECK-NEXT: store ptr [[T0]], ptr [[X]],
 
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
   // CHECK-NOT:  imprecise_release
 
   // CHECK-NEXT: ret void  

diff  --git a/clang/test/CodeGenObjC/arc-related-result-type.m b/clang/test/CodeGenObjC/arc-related-result-type.m
index cf65baddc5fc8..3bb3dfb60636f 100644
--- a/clang/test/CodeGenObjC/arc-related-result-type.m
+++ b/clang/test/CodeGenObjC/arc-related-result-type.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
 
 @interface Test0
 - (id) self;
@@ -7,22 +7,16 @@ void test0(Test0 *val) {
   Test0 *x = [val self];
 
 // CHECK-LABEL:    define{{.*}} void @test0(
-// CHECK:      [[VAL:%.*]] = alloca [[TEST0:%.*]]*
-// CHECK-NEXT: [[X:%.*]] = alloca [[TEST0]]*
-// CHECK-NEXT: store [[TEST0]]* null
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: bitcast
+// CHECK:      [[VAL:%.*]] = alloca ptr
+// CHECK-NEXT: [[X:%.*]] = alloca ptr
+// CHECK-NEXT: store ptr null
 // CHECK-NEXT: call void @llvm.objc.storeStrong(
-// CHECK-NEXT: load [[TEST0]]*, [[TEST0]]** [[VAL]],
-// CHECK-NEXT: bitcast
+// CHECK-NEXT: load ptr, ptr [[VAL]],
 // CHECK-NEXT: load
-// CHECK-NEXT: [[T0:%.*]] = call i8* bitcast (
-// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
-// CHECK-NEXT: store [[TEST0]]* [[T2]], [[TEST0]]** [[X]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[X]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[VAL]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: [[T0:%.*]] = call ptr
+// CHECK-NEXT: [[T1:%.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[X]]
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[VAL]], ptr null)
 // CHECK-NEXT: ret void
 }

diff  --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m
index 25295769f74dc..05a3a647b818a 100644
--- a/clang/test/CodeGenObjC/arc.m
+++ b/clang/test/CodeGenObjC/arc.m
@@ -1,66 +1,64 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s
 
 // rdar://13129783. Check both native/non-native arc platforms. Here we check
 // that they treat nonlazybind 
diff erently.
-// RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
-// RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
-
-// ARC-ALIEN: declare extern_weak void @llvm.objc.storeStrong(i8**, i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retain(i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.autoreleaseReturnValue(i8*)
-// ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
-// ARC-ALIEN: declare extern_weak void @llvm.objc.release(i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.initWeak(i8**, i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.storeWeak(i8**, i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.loadWeakRetained(i8**)
-// ARC-ALIEN: declare extern_weak void @llvm.objc.destroyWeak(i8**)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.autorelease(i8*)
-// ARC-ALIEN: declare extern_weak i8* @llvm.objc.retainAutorelease(i8*)
-
-// ARC-NATIVE: declare void @llvm.objc.storeStrong(i8**, i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.retain(i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
-// ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
-// ARC-NATIVE: declare void @llvm.objc.release(i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.initWeak(i8**, i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.storeWeak(i8**, i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.loadWeakRetained(i8**)
-// ARC-NATIVE: declare void @llvm.objc.destroyWeak(i8**)
-// ARC-NATIVE: declare i8* @llvm.objc.autorelease(i8*)
-// ARC-NATIVE: declare i8* @llvm.objc.retainAutorelease(i8*)
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
+
+// ARC-ALIEN: declare extern_weak void @llvm.objc.storeStrong(ptr, ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retain(ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autoreleaseReturnValue(ptr)
+// ARC-ALIEN: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
+// ARC-ALIEN: declare extern_weak void @llvm.objc.release(ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.initWeak(ptr, ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.storeWeak(ptr, ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.loadWeakRetained(ptr)
+// ARC-ALIEN: declare extern_weak void @llvm.objc.destroyWeak(ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autorelease(ptr)
+// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutorelease(ptr)
+
+// ARC-NATIVE: declare void @llvm.objc.storeStrong(ptr, ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.retain(ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.autoreleaseReturnValue(ptr)
+// ARC-NATIVE: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
+// ARC-NATIVE: declare void @llvm.objc.release(ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.initWeak(ptr, ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.storeWeak(ptr, ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.loadWeakRetained(ptr)
+// ARC-NATIVE: declare void @llvm.objc.destroyWeak(ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.autorelease(ptr)
+// ARC-NATIVE: declare ptr @llvm.objc.retainAutorelease(ptr)
 
 // CHECK-LABEL: define{{.*}} void @test0
 void test0(id x) {
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{.*}})
-  // CHECK-NEXT: store i8* [[PARM]], i8** [[X]]
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: [[PARM:%.*]] = call ptr @llvm.objc.retain(ptr {{.*}})
+  // CHECK-NEXT: store ptr [[PARM]], ptr [[X]]
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]])
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL: define{{.*}} i8* @test1(i8*
+// CHECK-LABEL: define{{.*}} ptr @test1(ptr
 id test1(id x) {
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[Y:%.*]] = alloca i8*
-  // CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}})
-  // CHECK-NEXT: store i8* [[PARM]], i8** [[X]]
-  // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[Y]]
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: [[RET:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]])
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-  // CHECK-NEXT: [[T1:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[RET]])
-  // CHECK-NEXT: ret i8* [[T1]]
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: [[Y:%.*]] = alloca ptr
+  // CHECK-NEXT: [[PARM:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}})
+  // CHECK-NEXT: store ptr [[PARM]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: store ptr null, ptr [[Y]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: [[RET:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
+  // CHECK-NEXT: [[T1:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[RET]])
+  // CHECK-NEXT: ret ptr [[T1]]
   id y;
   return y;
 }
@@ -100,102 +98,83 @@ - (id) copy;
 void test3_unelided(void) {
   extern void test3_helper(void);
 
-  // CHECK:      [[X:%.*]] = alloca [[TEST3:%.*]]*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast [[TEST3]]** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store [[TEST3]]* null, [[TEST3]]** [[X]], align
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]], align
   Test3 *x;
 
   // Call to +alloc.
-  // CHECK-NEXT: load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: call void @llvm.objc.release(i8*
+  // CHECK-NEXT: load {{.*}}, ptr @"OBJC_CLASSLIST_REFERENCES_
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[ALLOC:%.*]] = call ptr @objc_msgSend
+  // CHECK-NEXT: call void @llvm.objc.release(ptr
   [Test3 alloc];
 
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* noundef [[T1]],
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[COPY]]) [[NUW:#[0-9]+]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[COPY:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]],
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[COPY]]) [[NUW:#[0-9]+]]
   [x copy];
 
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]]
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST3]]** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
 // CHECK-LABEL: define{{.*}} void @test3()
 void test3(void) {
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
 
   id x = [[Test3 alloc] initWith: 5];
 
   // Call to +alloc.
-  // CHECK-NEXT: load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: load {{.*}}, ptr @"OBJC_CLASSLIST_REFERENCES_
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[ALLOC:%.*]] = call ptr @objc_msgSend
 
   // Call to -initWith: with elided retain of consumed argument.
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8*
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: [[INIT:%.*]] = bitcast
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[INIT:%.*]] = call ptr @objc_msgSend(ptr
   // Assignment for initialization, retention elided.
-  // CHECK-NEXT: store i8* [[INIT]], i8** [[X]]
+  // CHECK-NEXT: store ptr [[INIT]], ptr [[X]]
 
   // Call to -copy.
-  // CHECK-NEXT: [[V:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* noundef [[V]],
+  // CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[COPY:%.*]] = call ptr @objc_msgSend(ptr noundef [[V]],
 
   // Assignment to x.
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: store i8* [[COPY]], i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]]
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr [[COPY]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]]) [[NUW]]
 
   x = [x copy];
 
   // Cleanup for x.
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]]
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]]) [[NUW]]
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL: define{{.*}} i8* @test4()
+// CHECK-LABEL: define{{.*}} ptr @test4()
 id test4(void) {
   // Call to +alloc.
-  // CHECK:      load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-  // CHECK-NEXT: [[ALLOC:%.*]] = bitcast
+  // CHECK:      load {{.*}}, ptr @"OBJC_CLASSLIST_REFERENCES_
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[ALLOC:%.*]] = call ptr @objc_msgSend
 
   // Call to -initWith: with elided retain of consumed argument.
-  // CHECK-NEXT: [[ALLOC:%.*]] = bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* noundef [[ALLOC]],
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[INIT:%.*]] = call ptr @objc_msgSend(ptr noundef [[ALLOC]],
 
   // Initialization of return value, occurring within full-expression.
   // Retain/release elided.
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: [[INIT:%.*]] = bitcast
-  // CHECK-NEXT: [[RET:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[INIT]])
+  // CHECK-NEXT: [[RET:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[INIT]])
 
-  // CHECK-NEXT: ret i8* [[RET]]
+  // CHECK-NEXT: ret ptr [[RET]]
 
   return [[Test3 alloc] initWith: 6];
 }
@@ -209,58 +188,49 @@ @interface Test5 {
 // CHECK-LABEL: define{{.*}} void @test5
 void test5(Test5 *x, id y) {
   // Prologue.
-  // CHECK:      [[X:%.*]] = alloca [[TEST5:%.*]]*,
-  // CHECK-NEXT: [[Y:%.*]] = alloca i8*
-  // CHECK-NEXT: bitcast [[TEST5]]* {{%.*}} to i8*
-  // CHECK-NEXT: call i8* @llvm.objc.retain
-  // CHECK-NEXT: [[PARMX:%.*]] = bitcast i8* {{%.*}} to [[TEST5]]*
-  // CHECK-NEXT: store [[TEST5]]* [[PARMX]], [[TEST5]]** [[X]]
-  // CHECK-NEXT: call i8* @llvm.objc.retain
+  // CHECK:      [[X:%.*]] = alloca ptr,
+  // CHECK-NEXT: [[Y:%.*]] = alloca ptr
+  // CHECK-NEXT: call ptr @llvm.objc.retain
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[X]]
+  // CHECK-NEXT: call ptr @llvm.objc.retain
   // CHECK-NEXT: store
 
-  // CHECK-NEXT: load [[TEST5]]*, [[TEST5]]** [[X]]
-  // CHECK-NEXT: load i64, i64* @"OBJC_IVAR_$_Test5.var"
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: getelementptr
-  // CHECK-NEXT: [[VAR:%.*]] = bitcast
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[VAR]]
-  // CHECK-NEXT: store i8* null, i8** [[VAR]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]]
+  // CHECK-NEXT: load ptr, ptr [[X]]
+  // CHECK-NEXT: load i64, ptr @"OBJC_IVAR_$_Test5.var"
+  // CHECK-NEXT: [[VAR:%.*]] = getelementptr
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: store ptr null, ptr [[VAR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]]) [[NUW]]
   x->var = 0;
 
-  // CHECK-NEXT: [[YVAL:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: load [[TEST5]]*, [[TEST5]]** [[X]]
-  // CHECK-NEXT: load i64, i64* @"OBJC_IVAR_$_Test5.var"
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: getelementptr
-  // CHECK-NEXT: [[VAR:%.*]] = bitcast
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[YVAL]]) [[NUW]]
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[VAR]]
-  // CHECK-NEXT: store i8* [[T0]], i8** [[VAR]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]]
+  // CHECK-NEXT: [[YVAL:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: load ptr, ptr [[X]]
+  // CHECK-NEXT: load i64, ptr @"OBJC_IVAR_$_Test5.var"
+  // CHECK-NEXT: [[VAR:%.*]] = getelementptr
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr [[YVAL]]) [[NUW]]
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: store ptr [[T0]], ptr [[VAR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]]) [[NUW]]
   x->var = y;
 
   // Epilogue.
-  // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[TMP]]) [[NUW]]
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]*, [[TEST5]]** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]]
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP]]) [[NUW]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
   // CHECK-NEXT: ret void
 }
 
 id test6_helper(void) __attribute__((ns_returns_retained));
 // CHECK-LABEL: define{{.*}} void @test6()
 void test6(void) {
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[CALL:%.*]] = call i8* @test6_helper()
-  // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[CALL:%.*]] = call ptr @test6_helper()
+  // CHECK-NEXT: store ptr [[CALL]], ptr [[X]]
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
   id x = test6_helper();
 }
@@ -268,17 +238,15 @@ void test6(void) {
 void test7_helper(id __attribute__((ns_consumed)));
 // CHECK-LABEL: define{{.*}} void @test7()
 void test7(void) {
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[X]]
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) [[NUW]]
-  // CHECK-NEXT: call void @test7_helper(i8* noundef [[T1]])
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW]]
+  // CHECK-NEXT: call void @test7_helper(ptr noundef [[T1]])
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
   id x;
   test7_helper(x);
@@ -287,14 +255,12 @@ void test7(void) {
 id test8_helper(void) __attribute__((ns_returns_retained));
 void test8(void) {
   __unsafe_unretained id x = test8_helper();
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper()
-  // CHECK-NEXT: store i8* [[T0]], i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @test8_helper()
+  // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -306,52 +272,41 @@ void test10(void) {
   id y = x.me.me;
 
   // CHECK-LABEL:      define{{.*}} void @test10()
-  // CHECK:      [[X:%.*]] = alloca [[TEST10:%.*]]*, align
-  // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast [[TEST10]]** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store [[TEST10]]* null, [[TEST10]]** [[X]]
-  // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
-  // CHECK-NEXT: load [[TEST10]]*, [[TEST10]]** [[X]], align
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
-  // CHECK-NEXT: [[V:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[V]])
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
-  // CHECK-NEXT: [[T3:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[T3]])
-  // CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8*
-  // CHECK-NEXT: store i8* [[T4]], i8** [[Y]]
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST10]]* [[V]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST10]]*, [[TEST10]]** [[X]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST10]]** [[X]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr, align
+  // CHECK-NEXT: [[Y:%.*]] = alloca ptr, align
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: load ptr, ptr [[X]], align
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
+  // CHECK-NEXT: [[V:%.*]] = call ptr @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[V]])
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T3]])
+  // CHECK-NEXT: store ptr [[T3]], ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[V]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
 void test11(id (*f)(void) __attribute__((ns_returns_retained))) {
   // CHECK-LABEL:      define{{.*}} void @test11(
-  // CHECK:      [[F:%.*]] = alloca i8* ()*, align
-  // CHECK-NEXT: [[X:%.*]] = alloca i8*, align
-  // CHECK-NEXT: store i8* ()* {{%.*}}, i8* ()** [[F]], align
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8* ()*, i8* ()** [[F]], align
-  // CHECK-NEXT: [[T1:%.*]] = call i8* [[T0]]()
-  // CHECK-NEXT: store i8* [[T1]], i8** [[X]], align
-  // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[F:%.*]] = alloca ptr, align
+  // CHECK-NEXT: [[X:%.*]] = alloca ptr, align
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[F]], align
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[F]], align
+  // CHECK-NEXT: [[T1:%.*]] = call ptr [[T0]]()
+  // CHECK-NEXT: store ptr [[T1]], ptr [[X]], align
+  // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
   id x = f();
 }
@@ -360,72 +315,63 @@ void test12(void) {
   extern id test12_helper(void);
 
   // CHECK-LABEL:      define{{.*}} void @test12()
-  // CHECK:      [[X:%.*]] = alloca i8*, align
-  // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align
+  // CHECK:      [[X:%.*]] = alloca ptr, align
+  // CHECK-NEXT: [[Y:%.*]] = alloca ptr, align
 
   __weak id x = test12_helper();
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[X]], i8* [[T1]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @test12_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[X]], ptr [[T1]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
 
   x = test12_helper();
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T1]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @test12_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[X]], ptr [[T1]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
 
   id y = x;
-  // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[X]])
-  // CHECK-NEXT: store i8* [[T2]], i8** [[Y]], align
-
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]])
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]])
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[X]])
+  // CHECK-NEXT: store ptr [[T2]], ptr [[Y]], align
+
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[X]])
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK: ret void
 }
 
 // Indirect consuming calls.
 void test13(void) {
   // CHECK-LABEL:      define{{.*}} void @test13()
-  // CHECK:      [[X:%.*]] = alloca i8*, align
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[X]], align
+  // CHECK:      [[X:%.*]] = alloca ptr, align
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]], align
   id x;
 
   typedef void fnty(id __attribute__((ns_consumed)));
   extern fnty *test13_func;
-  // CHECK-NEXT: [[FN:%.*]] = load void (i8*)*, void (i8*)** @test13_func, align
-  // CHECK-NEXT: [[X_VAL:%.*]] = load i8*, i8** [[X]], align
-  // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @llvm.objc.retain(i8* [[X_VAL]]) [[NUW]]
-  // CHECK-NEXT: call void [[FN]](i8* noundef [[X_TMP]])
+  // CHECK-NEXT: [[FN:%.*]] = load ptr, ptr @test13_func, align
+  // CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align
+  // CHECK-NEXT: [[X_TMP:%.*]] = call ptr @llvm.objc.retain(ptr [[X_VAL]]) [[NUW]]
+  // CHECK-NEXT: call void [[FN]](ptr noundef [[X_TMP]])
   test13_func(x);
 
   extern fnty ^test13_block;
-  // CHECK-NEXT: [[TMP:%.*]] = load void (i8*)*, void (i8*)** @test13_block, align
-  // CHECK-NEXT: [[BLOCK:%.*]] = bitcast void (i8*)* [[TMP]] to [[BLOCKTY:%.*]]*
-  // CHECK-NEXT: [[BLOCK_FN_PTR:%.*]] = getelementptr inbounds [[BLOCKTY]], [[BLOCKTY]]* [[BLOCK]], i32 0, i32 3
-  // CHECK-NEXT: [[BLOCK_OPAQUE:%.*]] = bitcast [[BLOCKTY]]* [[BLOCK]] to i8*
-  // CHECK-NEXT: [[X_VAL:%.*]] = load i8*, i8** [[X]], align
-  // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @llvm.objc.retain(i8* [[X_VAL]]) [[NUW]]
-  // CHECK-NEXT: [[BLOCK_FN_TMP:%.*]] = load i8*, i8** [[BLOCK_FN_PTR]]
-  // CHECK-NEXT: [[BLOCK_FN:%.*]] = bitcast i8* [[BLOCK_FN_TMP]] to void (i8*, i8*)*
-  // CHECK-NEXT: call void [[BLOCK_FN]](i8* noundef [[BLOCK_OPAQUE]], i8* noundef [[X_TMP]])
+  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr @test13_block, align
+  // CHECK-NEXT: [[BLOCK_FN_PTR:%.*]] = getelementptr inbounds [[BLOCKTY:%.*]], ptr [[TMP]], i32 0, i32 3
+  // CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align
+  // CHECK-NEXT: [[X_TMP:%.*]] = call ptr @llvm.objc.retain(ptr [[X_VAL]]) [[NUW]]
+  // CHECK-NEXT: [[BLOCK_FN_TMP:%.*]] = load ptr, ptr [[BLOCK_FN_PTR]]
+  // CHECK-NEXT: call void [[BLOCK_FN_TMP]](ptr noundef [[TMP]], ptr noundef [[X_TMP]])
   test13_block(x);
 
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]]
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
+  // CHECK-NEXT: void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -442,47 +388,41 @@ @implementation Test16
 @synthesize y;
 - (void) dealloc {
   // CHECK:    define internal void @"\01-[Test16 dealloc]"(
-  // CHECK:      [[SELF:%.*]] = alloca [[TEST16:%.*]]*, align
-  // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align
+  // CHECK:      [[SELF:%.*]] = alloca ptr, align
+  // CHECK-NEXT: [[CMD:%.*]] = alloca ptr, align
   // CHECK-NEXT: alloca
-  // CHECK-NEXT: store [[TEST16]]* {{%.*}}, [[TEST16]]** [[SELF]], align
-  // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
-  // CHECK-NEXT: [[BASE:%.*]] = load [[TEST16]]*, [[TEST16]]** [[SELF]]
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]], align
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[CMD]]
+  // CHECK-NEXT: [[BASE:%.*]] = load ptr, ptr [[SELF]]
 
   // Call super.
-  // CHECK-NEXT: [[BASE2:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8*
   // CHECK-NEXT: [[T0:%.*]] = getelementptr
-  // CHECK-NEXT: store i8* [[BASE2]], i8** [[T0]]
-  // CHECK-NEXT: load {{%.*}}*, {{%.*}}** @"OBJC_CLASSLIST_SUP_REFS_$_
-  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: store ptr [[BASE]], ptr [[T0]]
+  // CHECK-NEXT: load ptr, ptr @"OBJC_CLASSLIST_SUP_REFS_$_
   // CHECK-NEXT: getelementptr
   // CHECK-NEXT: store
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: call void bitcast (i8* ({{.*}})* @objc_msgSendSuper2 to void (
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: call void @objc_msgSendSuper2(
   // CHECK-NEXT: ret void
 }
 
 // .cxx_destruct
   // CHECK:    define internal void @"\01-[Test16 .cxx_destruct]"(
-  // CHECK:      [[SELF:%.*]] = alloca [[TEST16:%.*]]*, align
-  // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align
-  // CHECK-NEXT: store [[TEST16]]* {{%.*}}, [[TEST16]]** [[SELF]], align
-  // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
-  // CHECK-NEXT: [[BASE:%.*]] = load [[TEST16]]*, [[TEST16]]** [[SELF]]
+  // CHECK:      [[SELF:%.*]] = alloca ptr, align
+  // CHECK-NEXT: [[CMD:%.*]] = alloca ptr, align
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]], align
+  // CHECK-NEXT: store ptr {{%.*}}, ptr [[CMD]]
+  // CHECK-NEXT: [[BASE:%.*]] = load ptr, ptr [[SELF]]
 
   // Destroy y.
-  // CHECK-NEXT: [[Y_OFF:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test16.y"
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8*
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[Y_OFF]]
-  // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8**
-  // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null) [[NUW]]
+  // CHECK-NEXT: [[Y_OFF:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test16.y"
+  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[BASE]], i64 [[Y_OFF]]
+  // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null) [[NUW]]
 
   // Destroy z.
-  // CHECK-NEXT: [[Z_OFF:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test16.z"
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8*
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[Z_OFF]]
-  // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8**
-  // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null) [[NUW]]
+  // CHECK-NEXT: [[Z_OFF:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test16.z"
+  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[BASE]], i64 [[Z_OFF]]
+  // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null) [[NUW]]
 
   // CHECK-NEXT: ret void
 
@@ -500,31 +440,30 @@ - (int) x { return super.x + 1; }
 
 void test19(void) {
   // CHECK-LABEL: define{{.*}} void @test19()
-  // CHECK:      [[X:%.*]] = alloca [5 x i8*], align 16
+  // CHECK:      [[X:%.*]] = alloca [5 x ptr], align 16
   // CHECK: call void @llvm.lifetime.start
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8*
-  // CHECK: call void @llvm.memset.p0i8.i64(i8* align 16 [[T0]], i8 0, i64 40, i1 false)
+  // CHECK: call void @llvm.memset.p0.i64(ptr align 16 [[X]], i8 0, i64 40, i1 false)
   id x[5];
 
   extern id test19_helper(void);
   x[2] = test19_helper();
 
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @test19_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i64 0, i64 2
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]]
-  // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]]
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @test19_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x ptr], ptr [[X]], i64 0, i64 2
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]]
+  // CHECK-NEXT: store ptr [[T1]], ptr [[SLOT]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]]
 
-  // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i32 0, i32 0
-  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 5
+  // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x ptr], ptr [[X]], i32 0, i32 0
+  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 5
   // CHECK-NEXT: br label
 
-  // CHECK:      [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
-  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+  // CHECK:      [[AFTER:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds ptr, ptr [[AFTER]], i64 -1
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[CUR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: [[EQ:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]
   // CHECK-NEXT: br i1 [[EQ]],
 
   // CHECK:      ret void
@@ -533,95 +472,93 @@ void test19(void) {
 void test20(unsigned n) {
   // CHECK-LABEL: define{{.*}} void @test20
   // CHECK:      [[N:%.*]] = alloca i32, align 4
-  // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca i8*
+  // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca ptr
   // CHECK-NEXT: [[VLA_EXPR:%.*]] = alloca i64, align 8
-  // CHECK-NEXT: store i32 {{%.*}}, i32* [[N]], align 4
+  // CHECK-NEXT: store i32 {{%.*}}, ptr [[N]], align 4
 
   id x[n];
 
   // Capture the VLA size.
-  // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
+  // CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[N]], align 4
   // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64
 
   // Save the stack pointer.
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave()
-  // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]]
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.stacksave()
+  // CHECK-NEXT: store ptr [[T0]], ptr [[SAVED_STACK]]
 
   // Allocate the VLA.
-  // CHECK-NEXT: [[VLA:%.*]] = alloca i8*, i64 [[DIM]], align 16
+  // CHECK-NEXT: [[VLA:%.*]] = alloca ptr, i64 [[DIM]], align 16
 
   // Store the VLA #elements expression.
-  // CHECK-NEXT: store i64 [[DIM]], i64* [[VLA_EXPR]], align 8
+  // CHECK-NEXT: store i64 [[DIM]], ptr [[VLA_EXPR]], align 8
 
   // Zero-initialize.
-  // CHECK-NEXT: [[T0:%.*]] = bitcast i8** [[VLA]] to i8*
   // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[DIM]], 8
-  // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 [[T0]], i8 0, i64 [[T1]], i1 false)
+  // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[VLA]], i8 0, i64 [[T1]], i1 false)
 
   // Destroy.
-  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[VLA]], i64 [[DIM]]
-  // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq i8** [[VLA]], [[END]]
+  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[VLA]], i64 [[DIM]]
+  // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq ptr [[VLA]], [[END]]
   // CHECK-NEXT: br i1 [[EMPTY]]
 
-  // CHECK:      [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
-  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[VLA]]
+  // CHECK:      [[AFTER:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds ptr, ptr [[AFTER]], i64 -1
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[CUR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: [[EQ:%.*]] = icmp eq ptr [[CUR]], [[VLA]]
   // CHECK-NEXT: br i1 [[EQ]],
 
-  // CHECK:      [[T0:%.*]] = load i8*, i8** [[SAVED_STACK]]
-  // CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]])
+  // CHECK:      [[T0:%.*]] = load ptr, ptr [[SAVED_STACK]]
+  // CHECK-NEXT: call void @llvm.stackrestore(ptr [[T0]])
   // CHECK-NEXT: ret void
 }
 
 void test21(unsigned n) {
   // CHECK-LABEL: define{{.*}} void @test21
   // CHECK:      [[N:%.*]] = alloca i32, align 4
-  // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca i8*
+  // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca ptr
   // CHECK-NEXT: [[VLA_EXPR:%.*]] = alloca i64, align 8
-  // CHECK-NEXT: store i32 {{%.*}}, i32* [[N]], align 4
+  // CHECK-NEXT: store i32 {{%.*}}, ptr [[N]], align 4
 
   id x[2][n][3];
 
   // Capture the VLA size.
-  // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
+  // CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[N]], align 4
   // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64
 
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave()
-  // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]]
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.stacksave()
+  // CHECK-NEXT: store ptr [[T0]], ptr [[SAVED_STACK]]
 
 
   // Allocate the VLA.
   // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]]
-  // CHECK-NEXT: [[VLA:%.*]] = alloca [3 x i8*], i64 [[T0]], align 16
+  // CHECK-NEXT: [[VLA:%.*]] = alloca [3 x ptr], i64 [[T0]], align 16
 
   // Store the VLA #elements expression.
-  // CHECK-NEXT: store i64 [[DIM]], i64* [[VLA_EXPR]], align 8
+  // CHECK-NEXT: store i64 [[DIM]], ptr [[VLA_EXPR]], align 8
 
   // Zero-initialize.
-  // CHECK-NEXT: [[T0:%.*]] = bitcast [3 x i8*]* [[VLA]] to i8*
   // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 2, [[DIM]]
   // CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[T1]], 24
-  // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 [[T0]], i8 0, i64 [[T2]], i1 false)
+  // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[VLA]], i8 0, i64 [[T2]], i1 false)
 
   // Destroy.
   // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]]
-  // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[VLA]], i32 0, i32 0
+  // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [3 x ptr], ptr [[VLA]], i32 0, i32 0
   // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[T0]], 3
-  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[T1]]
-  // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq i8** [[BEGIN]], [[END]]
+  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 [[T1]]
+  // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq ptr [[BEGIN]], [[END]]
   // CHECK-NEXT: br i1 [[EMPTY]]
 
-  // CHECK:      [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
-  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
-  // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+  // CHECK:      [[AFTER:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+  // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds ptr, ptr [[AFTER]], i64 -1
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[CUR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) [[NUW]], !clang.imprecise_release
+  // CHECK-NEXT: [[EQ:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]
   // CHECK-NEXT: br i1 [[EQ]],
 
-  // CHECK:      [[T0:%.*]] = load i8*, i8** [[SAVED_STACK]]
-  // CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]])
+  // CHECK:      [[T0:%.*]] = load ptr, ptr [[SAVED_STACK]]
+  // CHECK-NEXT: call void @llvm.stackrestore(ptr [[T0]])
   // CHECK-NEXT: ret void
 }
 
@@ -642,18 +579,16 @@ @implementation Test24 @end
 @interface Test26 { id x[4]; } @end
 @implementation Test26 @end
 // CHECK:    define internal void @"\01-[Test26 .cxx_destruct]"(
-// CHECK:      [[SELF:%.*]] = load [[TEST26:%.*]]*, [[TEST26:%.*]]**
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test26.x"
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST26]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]]
-// CHECK-NEXT: [[X:%.*]] = bitcast i8* [[T1]] to [4 x i8*]*
-// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[X]], i32 0, i32 0
-// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 4
+// CHECK:      [[SELF:%.*]] = load ptr, ptr
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test26.x"
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
+// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x ptr], ptr [[T1]], i32 0, i32 0
+// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 4
 // CHECK-NEXT: br label
-// CHECK:      [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
-// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[CUR]], i8* null)
-// CHECK-NEXT: [[ISDONE:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+// CHECK:      [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+// CHECK-NEXT: [[CUR]] = getelementptr inbounds ptr, ptr [[PAST]], i64 -1
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[CUR]], ptr null)
+// CHECK-NEXT: [[ISDONE:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]
 // CHECK-NEXT: br i1 [[ISDONE]],
 // CHECK:      ret void
 
@@ -663,20 +598,16 @@ - (id) init;
 @end
 @implementation Test27
 - (id) init { return self; }
-// CHECK:    define internal i8* @"\01-[Test27 init]"
-// CHECK:      [[SELF:%.*]] = alloca [[TEST27:%.*]]*,
-// CHECK-NEXT: [[CMD:%.*]] = alloca i8*,
-// CHECK-NEXT: store [[TEST27]]* {{%.*}}, [[TEST27]]** [[SELF]]
-// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]*
-// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8*
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK:    define internal ptr @"\01-[Test27 init]"
+// CHECK:      [[SELF:%.*]] = alloca ptr,
+// CHECK-NEXT: [[CMD:%.*]] = alloca ptr,
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]]
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[CMD]]
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+// CHECK-NEXT: ret ptr [[T2]]
 
 @end
 
@@ -688,12 +619,10 @@ @implementation Test28
 @synthesize prop;
 @end
 // CHECK:    define internal void @"\01-[Test28 .cxx_destruct]"
-// CHECK:      [[SELF:%.*]] = load [[TEST28:%.*]]*, [[TEST28:%.*]]**
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test28.prop"
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST28]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]]
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T2]], i8* null)
+// CHECK:      [[SELF:%.*]] = load ptr, ptr
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test28.prop"
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null)
 // CHECK-NEXT: ret void
 
 @interface Test29_super
@@ -706,65 +635,58 @@ - (id) initWithAllocator: (id) allocator;
 @implementation Test29
 static id _test29_allocator = 0;
 - (id) init {
-// CHECK:    define internal i8* @"\01-[Test29 init]"([[TEST29:%[^*]*]]* noundef {{%.*}},
-// CHECK:      [[SELF:%.*]] = alloca [[TEST29]]*, align 8
-// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8
-// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
+// CHECK:    define internal ptr @"\01-[Test29 init]"(ptr noundef {{%.*}},
+// CHECK:      [[SELF:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: [[CMD:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]]
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[CMD]]
 
 // Evaluate arguments.  Note that the send argument is evaluated
 // before the zeroing of self.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]], align 8
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @_test29_allocator, align 8
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]], align 8
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr @_test29_allocator, align 8
 
 // Implicit null of 'self', i.e. direct transfer of ownership.
-// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]]
+// CHECK-NEXT: store ptr null, ptr [[SELF]]
 
 // Actual message send.
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[T2]], i8* noundef [[SEL]], i8* noundef [[T1]])
+// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK-NEXT: [[CALL:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]], ptr noundef [[T1]])
 
 // Implicit write of result back into 'self'.  This is not supposed to
 // be detectable because we're supposed to ban accesses to the old
 // self value past the delegate init call.
-// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]*
-// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]]
+// CHECK-NEXT: store ptr [[CALL]], ptr [[SELF]]
 
 // Return statement.
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]]
-// CHECK-NEXT: [[CALL:%.*]] = bitcast
-// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[CALL]]) [[NUW]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
-// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
+// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]]) [[NUW]]
 
 // Cleanup.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]]) [[NUW]], !clang.imprecise_release
 
 // Return.
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-NEXT: ret ptr [[T1]]
   return [self initWithAllocator: _test29_allocator];
 }
 - (id) initWithAllocator: (id) allocator {
-// CHECK:    define internal i8* @"\01-[Test29 initWithAllocator:]"(
-// CHECK:      [[SELF:%.*]] = alloca [[TEST29]]*, align 8
-// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8
-// CHECK-NEXT: [[ALLOCATOR:%.*]] = alloca i8*, align 8
+// CHECK:    define internal ptr @"\01-[Test29 initWithAllocator:]"(
+// CHECK:      [[SELF:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: [[CMD:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: [[ALLOCATOR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT: alloca
-// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
-// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}})
-// CHECK-NEXT: store i8* [[T0]], i8** [[ALLOCATOR]]
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]]
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[CMD]]
+// CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr {{%.*}})
+// CHECK-NEXT: store ptr [[T0]], ptr [[ALLOCATOR]]
 
 // Evaluate arguments.  Note that the send argument is evaluated
 // before the zeroing of self.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[ALLOCATOR]], align 8
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[ALLOCATOR]], align 8
 
 // Implicit null of 'self', i.e. direct transfer of ownership.
-// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]]
+// CHECK-NEXT: store ptr null, ptr [[SELF]]
 
 // Actual message send.
 // CHECK:      [[CALL:%.*]] = call {{.*}} @objc_msgSendSuper2
@@ -772,36 +694,27 @@ - (id) initWithAllocator: (id) allocator {
 // Implicit write of result back into 'self'.  This is not supposed to
 // be detectable because we're supposed to ban accesses to the old
 // self value past the delegate init call.
-// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]*
-// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]]
+// CHECK-NEXT: store ptr [[CALL]], ptr [[SELF]]
 
 // Assignment.
-// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]*
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]]
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST29]]*
-// CHECK-NEXT: [[T4:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]], align
-// CHECK-NEXT: store [[TEST29]]* [[T3]], [[TEST29]]** [[SELF]], align
-// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST29]]* [[T4]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]]) [[NUW]]
+// CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[SELF]], align
+// CHECK-NEXT: store ptr [[T2]], ptr [[SELF]], align
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]])
 
 // Return statement.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
-// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.retain(ptr [[T3]]) [[NUW]]
 
 // Cleanup.
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ALLOCATOR]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
+// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[ALLOCATOR]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T5]]) [[NUW]], !clang.imprecise_release
 
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+// CHECK-NEXT: [[T6:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T6]]) [[NUW]], !clang.imprecise_release
 
 // Return.
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-NEXT: ret ptr [[T4]]
   self = [super initWithAllocator: allocator];
   return self;
 }
@@ -816,64 +729,56 @@ @implementation Test30 {
 char *helper;
 }
 - (id) init {
-// CHECK:    define internal i8* @"\01-[Test30 init]"([[TEST30:%[^*]*]]* noundef {{%.*}},
-// CHECK:      [[RET:%.*]] = alloca [[TEST30]]*
-// CHECK-NEXT: alloca i8*
-// CHECK-NEXT: store [[TEST30]]* {{%.*}}, [[TEST30]]** [[SELF]]
+// CHECK:    define internal ptr @"\01-[Test30 init]"(ptr noundef {{%.*}},
+// CHECK:      [[RET:%.*]] = alloca ptr
+// CHECK-NEXT: alloca ptr
+// CHECK-NEXT: store ptr {{%.*}}, ptr [[SELF]]
 // CHECK-NEXT: store
 
 // Call.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-// CHECK-NEXT: [[CALL:%.*]] = call [[TEST30_HELPER:%.*]]* bitcast {{.*}} @objc_msgSend {{.*}}(i8* noundef [[T1]], i8* noundef [[SEL]])
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK-NEXT: [[CALL:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])
 
 // Assignment.
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST30_HELPER]]* [[CALL]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]
-// CHECK-NEXT: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test30.helper"
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T1]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[IVAR]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
-// CHECK-NEXT#: [[T5:%.*]] = load i8*, i8** [[T4]]
-// CHECK-NEXT#: [[T6:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-// CHECK-NEXT#: call void @llvm.objc.release(i8* [[T5]])
-// CHECK-NEXT: store i8* [[T0]], i8** [[T4]]
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test30.helper"
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[IVAR]]
+// CHECK-NEXT#: [[T5:%.*]] = load ptr, ptr [[T3]]
+// CHECK-NEXT#: [[T6:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]])
+// CHECK-NEXT#: call void @llvm.objc.release(ptr [[T5]])
+// CHECK-NEXT: store ptr [[CALL]], ptr [[T3]]
 
 // Return.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]*
-// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8*
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
 
 // Cleanup.
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[SELF]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
 
 // Epilogue.
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-NEXT: ret ptr [[T1]]
   self->helper = [self initHelper];
   return self;
 }
 - (Test30_helper*) initHelper {
-// CHECK:    define internal [[TEST30_HELPER]]* @"\01-[Test30 initHelper]"(
+// CHECK:    define internal ptr @"\01-[Test30 initHelper]"(
 // CHECK:      alloca
 // CHECK-NEXT: alloca
 // CHECK-NEXT: store
 // CHECK-NEXT: store
-// CHECK-NEXT: ret [[TEST30_HELPER]]* null
+// CHECK-NEXT: ret ptr null
   return 0;
 }
 
 @end
 
 __attribute__((ns_returns_retained)) id test32(void) {
-// CHECK-LABEL:    define{{.*}} i8* @test32()
-// CHECK:      [[T0:%.*]] = call i8* @test32_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
-// CHECK-NEXT: ret i8* [[T0]]
+// CHECK-LABEL:    define{{.*}} ptr @test32()
+// CHECK:      [[T0:%.*]] = call ptr @test32_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+// CHECK-NEXT: ret ptr [[T0]]
   extern id test32_helper(void);
   return test32_helper();
 }
@@ -894,84 +799,64 @@ void test33(Test33 *ptr) {
   [ptr takeStrong: &a];
   [ptr giveOut: &a];
 
-  // CHECK:    define{{.*}} void @test33([[TEST33:%.*]]*
-  // CHECK:      [[PTR:%.*]] = alloca [[TEST33]]*
-  // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]]*
-  // CHECK-NEXT: [[TEMP0:%.*]] = alloca [[A_T]]*
-  // CHECK-NEXT: [[TEMP1:%.*]] = alloca [[A_T]]*
-  // CHECK-NEXT: [[TEMP2:%.*]] = alloca [[A_T]]*
-  // CHECK-NEXT: bitcast
+  // CHECK:    define{{.*}} void @test33(ptr
+  // CHECK:      [[PTR:%.*]] = alloca ptr
+  // CHECK-NEXT: [[A:%.*]] = alloca ptr
+  // CHECK-NEXT: [[TEMP0:%.*]] = alloca ptr
+  // CHECK-NEXT: [[TEMP1:%.*]] = alloca ptr
+  // CHECK-NEXT: [[TEMP2:%.*]] = alloca ptr
   // CHECK-NEXT: llvm.objc.retain
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: store
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: call void @llvm.lifetime.start
-  // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]]
-
-  // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
-  // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
-  // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]]
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP0]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP0]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
-  // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
-  // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
-
-  // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
-  // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
-  // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]]
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP1]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP1]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
-  // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
-  // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
-
-  // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[A]])
-
-  // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[A]])
+  // CHECK-NEXT: store ptr null, ptr [[A]]
+
+  // CHECK-NEXT: load ptr, ptr [[PTR]]
+  // CHECK-NEXT: [[W0:%.*]] = load ptr, ptr [[A]]
+  // CHECK-NEXT: store ptr [[W0]], ptr [[TEMP0]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: objc_msgSend{{.*}}, ptr noundef [[TEMP0]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP0]]
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[W0]]) [[NUW]]
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[A]]
+  // CHECK-NEXT: store ptr [[T2]], ptr [[A]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]])
+
+  // CHECK-NEXT: load ptr, ptr [[PTR]]
+  // CHECK-NEXT: [[W0:%.*]] = load ptr, ptr [[A]]
+  // CHECK-NEXT: store ptr [[W0]], ptr [[TEMP1]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: objc_msgSend{{.*}}, ptr noundef [[TEMP1]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP1]]
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[W0]]) [[NUW]]
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[A]]
+  // CHECK-NEXT: store ptr [[T2]], ptr [[A]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]])
+
+  // CHECK-NEXT: load ptr, ptr [[PTR]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: objc_msgSend{{.*}}, ptr noundef [[A]])
+
+  // CHECK-NEXT: load ptr, ptr [[PTR]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: objc_msgSend{{.*}}, ptr noundef [[A]])
 
   // 'out'
-  // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
-  // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[TEMP2]]
-  // CHECK-NEXT: bitcast
-  // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP2]])
-  // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP2]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
-  // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
-  // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
-  // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
+  // CHECK-NEXT: load ptr, ptr [[PTR]]
+  // CHECK-NEXT: store ptr null, ptr [[TEMP2]]
+  // CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: objc_msgSend{{.*}}, ptr noundef [[TEMP2]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP2]]
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[A]]
+  // CHECK-NEXT: store ptr [[T2]], ptr [[A]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]])
 
   // CHECK-NEXT: load
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: llvm.objc.release
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: call void @llvm.lifetime.end
   // CHECK-NEXT: load
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: llvm.objc.release
   // CHECK-NEXT: ret void
 }
@@ -979,16 +864,16 @@ void test33(Test33 *ptr) {
 
 // CHECK-LABEL: define{{.*}} void @test36
 void test36(id x) {
-  // CHECK: [[X:%.*]] = alloca i8*
+  // CHECK: [[X:%.*]] = alloca ptr
 
-  // CHECK: call i8* @llvm.objc.retain
-  // CHECK: call i8* @llvm.objc.retain
-  // CHECK: call i8* @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
   id array[3] = { @"A", x, @"y" };
 
-  // CHECK:      [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: store i8* null, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+  // CHECK:      [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
   x = 0;
 
   // CHECK: br label
@@ -1006,32 +891,24 @@ void test37(void) {
   test37_helper(&var);
 
   // CHECK-LABEL:    define{{.*}} void @test37()
-  // CHECK:      [[VAR:%.*]] = alloca [[TEST37:%.*]]*,
-  // CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
-  // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast [[TEST37]]** [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]])
-  // CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]]
-
-  // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]]
-  // CHECK-NEXT: [[W1:%.*]] = bitcast [[TEST37]]* [[W0]] to i8*
-  // CHECK-NEXT: store i8* [[W1]], i8** [[TEMP]]
-  // CHECK-NEXT: call void @test37_helper(i8** noundef [[TEMP]])
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]*
-  // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8*
-  // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]])
-  // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]*
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[W1]]) [[NUW]]
-  // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]]
-  // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]]
-  // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T6]])
-
-  // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]]
-  // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8*
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-  // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[TEST37]]** [[VAR]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[VARPTR2]])
+  // CHECK:      [[VAR:%.*]] = alloca ptr,
+  // CHECK-NEXT: [[TEMP:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[VAR]])
+  // CHECK-NEXT: store ptr null, ptr [[VAR]]
+
+  // CHECK-NEXT: [[W0:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: store ptr [[W0]], ptr [[TEMP]]
+  // CHECK-NEXT: call void @test37_helper(ptr noundef [[TEMP]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP]]
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[W0]]) [[NUW]]
+  // CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: store ptr [[T3]], ptr [[VAR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T5]])
+
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[VAR]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[VAR]])
   // CHECK-NEXT: ret void
 }
 
@@ -1040,7 +917,7 @@ @implementation Test43
 - (id) test __attribute__((ns_returns_retained)) {
   extern id test43_produce(void);
   return test43_produce();
-  // CHECK:      call i8* @test43_produce(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK:      call ptr @test43_produce(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
   // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
   // CHECK-NEXT: ret
 }
@@ -1052,9 +929,9 @@ @interface Test45
 @implementation Test45
 @synthesize x;
 @end
-// CHECK:    define internal i8* @"\01-[Test45 x]"(
-// CHECK:      [[CALL:%.*]] = tail call i8* @objc_getProperty(
-// CHECK-NEXT: ret i8* [[CALL]]
+// CHECK:    define internal ptr @"\01-[Test45 x]"(
+// CHECK:      [[CALL:%.*]] = tail call ptr @objc_getProperty(
+// CHECK-NEXT: ret ptr [[CALL]]
 
 // rdar://problem/9315552
 void test46(__weak id *wp, __weak volatile id *wvp) {
@@ -1062,22 +939,22 @@ void test46(__weak id *wp, __weak volatile id *wvp) {
 
   // TODO: this is sub-optimal, we should retain at the actual call site.
 
-  // CHECK:      [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
-  // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
-  // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
-  // CHECK-NEXT: store i8* [[T4]], i8**
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK:      [[T1:%.*]] = call ptr @test46_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr {{%.*}}, align 8
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[T2]], ptr [[T1]])
+  // CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.retain(ptr [[T3]])
+  // CHECK-NEXT: store ptr [[T4]], ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   id x = *wp = test46_helper();
 
-  // CHECK:      [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
-  // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
-  // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
-  // CHECK-NEXT: store i8* [[T4]], i8**
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK:      [[T1:%.*]] = call ptr @test46_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr {{%.*}}, align 8
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[T2]], ptr [[T1]])
+  // CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.retain(ptr [[T3]])
+  // CHECK-NEXT: store ptr [[T4]], ptr
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   id y = *wvp = test46_helper();
 }
 
@@ -1087,23 +964,21 @@ void test47(void) {
   id x = x = test47_helper();
 
   // CHECK-LABEL:    define{{.*}} void @test47()
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[X]]
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @test47_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
-  // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: store i8* [[T0]], i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-  // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: store i8* [[T2]], i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]])
-  // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]])
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @test47_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+  // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr [[T2]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]])
+  // CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T4]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -1111,18 +986,16 @@ void test48(void) {
   extern id test48_helper(void);
   __weak id x = x = test48_helper();
   // CHECK-LABEL:    define{{.*}} void @test48()
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.initWeak(i8** [[X]], i8* null)
-  // CHECK-NEXT: [[T2:%.*]] = call i8* @test48_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T2]])
-  // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T2]])
-  // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T3]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
-  // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[X]])
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.objc.initWeak(ptr [[X]], ptr null)
+  // CHECK-NEXT: [[T2:%.*]] = call ptr @test48_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T2]])
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[X]], ptr [[T2]])
+  // CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[X]], ptr [[T3]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
+  // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[X]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -1130,18 +1003,16 @@ void test49(void) {
   extern id test49_helper(void);
   __autoreleasing id x = x = test49_helper();
   // CHECK-LABEL:    define{{.*}} void @test49()
-  // CHECK:      [[X:%.*]] = alloca i8*
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK-NEXT: store i8* null, i8** [[X]]
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @test49_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T0]])
-  // CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-  // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
-  // CHECK-NEXT: store i8* [[T3]], i8** [[X]]
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK-NEXT: store ptr null, ptr [[X]]
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @test49_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.autorelease(ptr [[T0]])
+  // CHECK-NEXT: store ptr [[T1]], ptr [[X]]
+  // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retainAutorelease(ptr [[T1]])
+  // CHECK-NEXT: store ptr [[T3]], ptr [[X]]
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -1149,7 +1020,7 @@ void test49(void) {
 id x(void);
 void test50(id y) {
   ({x();});
-// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain
+// CHECK: [[T0:%.*]] = call ptr @llvm.objc.retain
 // CHECK: call void @llvm.objc.release
 }
 
@@ -1174,20 +1045,18 @@ id test52(void) {
   id test52_helper(int) __attribute__((ns_returns_retained));
   return ({ int x = 5; test52_helper(x); });
 
-// CHECK-LABEL:    define{{.*}} i8* @test52()
+// CHECK-LABEL:    define{{.*}} ptr @test52()
 // CHECK:      [[X:%.*]] = alloca i32
-// CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca i8*
-// CHECK-NEXT: [[XPTR1:%.*]] = bitcast i32* [[X]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[XPTR1]])
-// CHECK-NEXT: store i32 5, i32* [[X]],
-// CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]],
-// CHECK-NEXT: [[T1:%.*]] = call i8* @test52_helper(i32 noundef [[T0]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[TMPALLOCA]]
-// CHECK-NEXT: [[XPTR2:%.*]] = bitcast i32* [[X]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[XPTR2]])
-// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[TMPALLOCA]]
-// CHECK-NEXT: [[T3:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T2]])
-// CHECK-NEXT: ret i8* [[T3]]
+// CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca ptr
+// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[X]])
+// CHECK-NEXT: store i32 5, ptr [[X]],
+// CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[X]],
+// CHECK-NEXT: [[T1:%.*]] = call ptr @test52_helper(i32 noundef [[T0]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[TMPALLOCA]]
+// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[X]])
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[TMPALLOCA]]
+// CHECK-NEXT: [[T3:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T2]])
+// CHECK-NEXT: ret ptr [[T3]]
 }
 
 // rdar://problem/9400644
@@ -1196,30 +1065,26 @@ void test53(void) {
   id x = ({ id y = test53_helper(); y; });
   (void) x;
 // CHECK-LABEL:    define{{.*}} void @test53()
-// CHECK:      [[X:%.*]] = alloca i8*,
-// CHECK-NEXT: [[Y:%.*]] = alloca i8*,
-// CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca i8*,
-// CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-// CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
-// CHECK-NEXT: [[T1:%.*]] = call i8* @test53_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]],
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]],
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[TMPALLOCA]]
-// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[Y]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
-// CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]])
-// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[TMPALLOCA]]
-// CHECK-NEXT: store i8* [[T3]], i8** [[X]],
-// CHECK-NEXT: load i8*, i8** [[X]],
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-// CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+// CHECK:      [[X:%.*]] = alloca ptr,
+// CHECK-NEXT: [[Y:%.*]] = alloca ptr,
+// CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca ptr,
+// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[Y]])
+// CHECK-NEXT: [[T1:%.*]] = call ptr @test53_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[Y]],
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]],
+// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[TMPALLOCA]]
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[Y]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
+// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[Y]])
+// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[TMPALLOCA]]
+// CHECK-NEXT: store ptr [[T3]], ptr [[X]],
+// CHECK-NEXT: load ptr, ptr [[X]],
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
 // CHECK-NEXT: ret void
 }
 
@@ -1229,7 +1094,7 @@ void test54(int first, ...) {
   __builtin_va_list arglist;
   // CHECK: call void @llvm.va_start
   __builtin_va_start(arglist, first);
-  // CHECK: call i8* @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
   id obj = __builtin_va_arg(arglist, id);
   // CHECK: call void @llvm.va_end
   __builtin_va_end(arglist);
@@ -1245,7 +1110,7 @@ - (void) dealloc {}
 @end
 // CHECK:   define internal void @"\01-[Test55(Category) dealloc]"(
 // CHECK-NOT: ret
-// CHECK:     call void bitcast (i8* ({{%.*}}*, i8*, ...)* @objc_msgSendSuper2 to void ({{%.*}}*, i8*)*)(
+// CHECK:     call void @objc_msgSendSuper2(
 
 // rdar://problem/8024350
 @protocol Test56Protocol
@@ -1253,27 +1118,25 @@ + (id) make __attribute__((ns_returns_retained));
 @end
 @interface Test56<Test56Protocol> @end
 @implementation Test56
-// CHECK: define internal i8* @"\01+[Test56 make]"(
+// CHECK: define internal ptr @"\01+[Test56 make]"(
 + (id) make {
   extern id test56_helper(void);
-  // CHECK:      [[T1:%.*]] = call i8* @test56_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: ret i8* [[T1]]
+  // CHECK:      [[T1:%.*]] = call ptr @test56_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: ret ptr [[T1]]
   return test56_helper();
 }
 @end
 void test56_test(void) {
   id x = [Test56 make];
   // CHECK-LABEL: define{{.*}} void @test56_test()
-  // CHECK:      [[X:%.*]] = alloca i8*, align 8
-  // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
-  // CHECK:      [[T0:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(
-  // CHECK-NEXT: store i8* [[T0]], i8** [[X]]
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
+  // CHECK:      [[X:%.*]] = alloca ptr, align 8
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
+  // CHECK:      [[T0:%.*]] = call ptr @objc_msgSend(
+  // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
   // CHECK-NEXT: ret void
 }
 
@@ -1286,33 +1149,27 @@ @interface Test57
 @implementation Test57
 @synthesize strong, weak, unsafe;
 @end
-// CHECK: define internal i8* @"\01-[Test57 strong]"(
-// CHECK:      [[T0:%.*]] = load [[TEST57:%.*]]*, [[TEST57:%.*]]** {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test57.strong"
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
-// CHECK-NEXT: [[T5:%.*]] = load i8*, i8** [[T4]]
-// CHECK-NEXT: ret i8* [[T5]]
-
-// CHECK: define internal i8* @"\01-[Test57 weak]"(
-// CHECK:      [[T0:%.*]] = load [[TEST57]]*, [[TEST57]]** {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test57.weak"
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
-// CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T4]])
-// CHECK-NEXT: [[T6:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T5]])
-// CHECK-NEXT: ret i8* [[T6]]
-
-// CHECK: define internal i8* @"\01-[Test57 unsafe]"(
-// CHECK:      [[T0:%.*]] = load [[TEST57]]*, [[TEST57]]** {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test57.unsafe"
-// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 [[T1]]
-// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
-// CHECK-NEXT: [[T5:%.*]] = load i8*, i8** [[T4]]
-// CHECK-NEXT: ret i8* [[T5]]
+// CHECK: define internal ptr @"\01-[Test57 strong]"(
+// CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.strong"
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
+// CHECK-NEXT: ret ptr [[T5]]
+
+// CHECK: define internal ptr @"\01-[Test57 weak]"(
+// CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.weak"
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T5:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T3]])
+// CHECK-NEXT: [[T6:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T5]])
+// CHECK-NEXT: ret ptr [[T6]]
+
+// CHECK: define internal ptr @"\01-[Test57 unsafe]"(
+// CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.unsafe"
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
+// CHECK-NEXT: ret ptr [[T5]]
 
 // rdar://problem/9842343
 void test59(void) {
@@ -1323,12 +1180,12 @@ void test59(void) {
   }
 
   // CHECK-LABEL:    define{{.*}} void @test59()
-  // CHECK:      [[T1:%.*]] = call i8* @test59_getlock(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]])
+  // CHECK:      [[T1:%.*]] = call ptr @test59_getlock(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: call i32 @objc_sync_enter(ptr [[T1]])
   // CHECK-NEXT: call void @test59_body()
-  // CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T1]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   // CHECK-NEXT: ret void
 }
 
@@ -1341,34 +1198,32 @@ - (id) test61_id;
 @end
 void test61(void) {
   // CHECK-LABEL:    define{{.*}} void @test61()
-  // CHECK:      [[Y:%.*]] = alloca i8*, align 8
+  // CHECK:      [[Y:%.*]] = alloca ptr, align 8
 
   extern id test61_make(void);
 
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
-  // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[T1]], i8* noundef [[T3]], i8* noundef [[T2]])
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: [[T0:%.*]] = call ptr @test61_make(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]])
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T4:%.*]] = call ptr @objc_msgSend(ptr noundef [[T1]], ptr noundef [[T3]], ptr noundef [[T2]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   [test61_make() performSelector: @selector(test61_void)];
 
-  // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
-  // CHECK-NEXT: [[T1:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-  // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: [[T5:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[T1]], i8* noundef [[T3]], i8* noundef [[T2]]){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T5]])
-  // CHECK-NEXT: store i8* [[T5]], i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[Y]])
+  // CHECK-NEXT: [[T1:%.*]] = call ptr @test61_make(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+  // CHECK-NEXT: [[T2:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[T5:%.*]] = call ptr @objc_msgSend(ptr noundef [[T1]], ptr noundef [[T3]], ptr noundef [[T2]]){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T5]])
+  // CHECK-NEXT: store ptr [[T5]], ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
   id y = [test61_make() performSelector: @selector(test61_id)];
 
-  // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-  // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[YPTR2]])
+  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
+  // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[Y]])
   // CHECK-NEXT: ret void
 }
 
@@ -1376,36 +1231,35 @@ void test61(void) {
 void test62(void) {
   // CHECK-LABEL:    define{{.*}} void @test62()
   // CHECK:      [[I:%.*]] = alloca i32, align 4
-  // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca i8*
+  // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca ptr
   // CHECK-NEXT: [[CLEANUP_REQUIRED:%.*]] = alloca i1
   extern id test62_make(void);
   extern void test62_body(void);
 
-  // CHECK-NEXT: [[IPTR:%.*]] = bitcast i32* [[I]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[IPTR]])
-  // CHECK-NEXT: store i32 0, i32* [[I]], align 4
+  // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]])
+  // CHECK-NEXT: store i32 0, ptr [[I]], align 4
   // CHECK-NEXT: br label
 
-  // CHECK:      [[T0:%.*]] = load i32, i32* [[I]], align 4
+  // CHECK:      [[T0:%.*]] = load i32, ptr [[I]], align 4
   // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 20
   // CHECK-NEXT: br i1 [[T1]],
 
   for (unsigned i = 0; i != 20; ++i) {
-    // CHECK:      [[T0:%.*]] = load i32, i32* [[I]], align 4
+    // CHECK:      [[T0:%.*]] = load i32, ptr [[I]], align 4
     // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
-    // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: store i1 false, ptr [[CLEANUP_REQUIRED]]
     // CHECK-NEXT: br i1 [[T1]],
-    // CHECK:      [[T1:%.*]] = call i8* @test62_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-    // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-    // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]]
-    // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]]
-    // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null
+    // CHECK:      [[T1:%.*]] = call ptr @test62_make(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+    // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+    // CHECK-NEXT: store ptr [[T1]], ptr [[CLEANUP_VALUE]]
+    // CHECK-NEXT: store i1 true, ptr [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: [[T2:%.*]] = icmp ne ptr [[T1]], null
     // CHECK-NEXT: br label
     // CHECK:      [[COND:%.*]] = phi i1 [ false, {{%.*}} ], [ [[T2]], {{%.*}} ]
-    // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: [[T0:%.*]] = load i1, ptr [[CLEANUP_REQUIRED]]
     // CHECK-NEXT: br i1 [[T0]],
-    // CHECK:      [[T0:%.*]] = load i8*, i8** [[CLEANUP_VALUE]]
-    // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
+    // CHECK:      [[T0:%.*]] = load ptr, ptr [[CLEANUP_VALUE]]
+    // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
     // CHECK-NEXT: br label
     // CHECK:      br i1 [[COND]]
     // CHECK:      call void @test62_body()
@@ -1415,9 +1269,9 @@ void test62(void) {
       test62_body();
   }
 
-  // CHECK:      [[T0:%.*]] = load i32, i32* [[I]], align 4
+  // CHECK:      [[T0:%.*]] = load i32, ptr [[I]], align 4
   // CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], 1
-  // CHECK-NEXT: store i32 [[T1]], i32* [[I]]
+  // CHECK-NEXT: store i32 [[T1]], ptr [[I]]
   // CHECK-NEXT: br label
 
   // CHECK:      ret void
@@ -1435,7 +1289,7 @@ @interface Person  {
 @implementation Person
 @synthesize address;
 @end
-// CHECK: tail call i8* @objc_getProperty
+// CHECK: tail call ptr @objc_getProperty
 // CHECK: call void @objc_setProperty
 
 // Verify that we successfully parse and preserve this attribute in
@@ -1449,21 +1303,19 @@ void test66(void) {
   [test66_receiver() consume: test66_arg()];
 }
 // CHECK-LABEL:    define{{.*}} void @test66()
-// CHECK:      [[T3:%.*]] = call [[TEST66:%.*]]* @test66_receiver(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST66]]* [[T3]])
-// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]])
-// CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8*
-// CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null
+// CHECK:      [[T3:%.*]] = call ptr @test66_receiver(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T3]])
+// CHECK-NEXT: [[T4:%.*]] = call ptr @test66_arg(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T4]])
+// CHECK-NEXT: [[SIX:%.*]] = icmp eq ptr [[T3]], null
 // CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label %[[CALL:.*]]
 // CHECK:      [[CALL]]:
-// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
-// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* noundef [[T7]], i8* noundef [[SEL]], i8* noundef [[T4]])
+// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[T3]], ptr noundef [[SEL]], ptr noundef [[T4]])
 // CHECK-NEXT: br label [[CONT:%.*]]
-// CHECK: call void @llvm.objc.release(i8* [[T4]]) [[NUW]]
+// CHECK: call void @llvm.objc.release(ptr [[T4]]) [[NUW]]
 // CHECK-NEXT: br label [[CONT:%.*]]
-// CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8*
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T8]])
+// CHECK: call void @llvm.objc.release(ptr [[T3]])
 // CHECK-NEXT: ret void
 
 // rdar://problem/9953540
@@ -1472,13 +1324,11 @@ void test67(void) {
   Class cl = test67_helper();
 }
 // CHECK-LABEL:    define{{.*}} void @test67()
-// CHECK:      [[CL:%.*]] = alloca i8*, align 8
-// CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]])
-// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper()
-// CHECK-NEXT: store i8* [[T0]], i8** [[CL]], align 8
-// CHECK-NEXT: [[CLPTR2:%.*]] = bitcast i8** [[CL]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CLPTR2]])
+// CHECK:      [[CL:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[CL]])
+// CHECK-NEXT: [[T0:%.*]] = call ptr @test67_helper()
+// CHECK-NEXT: store ptr [[T0]], ptr [[CL]], align 8
+// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[CL]])
 // CHECK-NEXT: ret void
 
 Class test68_helper(void);
@@ -1486,16 +1336,14 @@ void test68(void) {
   __strong Class cl = test67_helper();
 }
 // CHECK-LABEL:    define{{.*}} void @test68()
-// CHECK:      [[CL:%.*]] = alloca i8*, align 8
-// CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]])
-// CHECK-NEXT: [[T1:%.*]] = call i8* @test67_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8
-// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
-// CHECK-NEXT: [[CLPTR2:%.*]] = bitcast i8** [[CL]] to i8*
-// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CLPTR2]])
+// CHECK:      [[CL:%.*]] = alloca ptr, align 8
+// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[CL]])
+// CHECK-NEXT: [[T1:%.*]] = call ptr @test67_helper(){{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
+// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
+// CHECK-NEXT: store ptr [[T1]], ptr [[CL]], align 8
+// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[CL]]
+// CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
+// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[CL]])
 // CHECK-NEXT: ret void
 
 // rdar://problem/10564852
@@ -1503,19 +1351,18 @@ @interface Test69 @end
 @implementation Test69
 - (id) foo { return self; }
 @end
-// CHECK: define internal i8* @"\01-[Test69 foo]"(
-// CHECK:      [[SELF:%.*]] = alloca [[TEST69:%.*]]*, align 8
-// CHECK:      [[T0:%.*]] = load [[TEST69]]*, [[TEST69]]** [[SELF]], align 8
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST69]]* [[T0]] to i8*
-// CHECK-NEXT: ret i8* [[T1]]
+// CHECK: define internal ptr @"\01-[Test69 foo]"(
+// CHECK:      [[SELF:%.*]] = alloca ptr, align 8
+// CHECK:      [[T0:%.*]] = load ptr, ptr [[SELF]], align 8
+// CHECK-NEXT: ret ptr [[T0]]
 
 // rdar://problem/10907547
 void test70(id i) {
   // CHECK-LABEL: define{{.*}} void @test70
-  // CHECK: store i8* null, i8**
-  // CHECK: store i8* null, i8**
-  // CHECK: [[ID:%.*]] = call i8* @llvm.objc.retain(i8*
-  // CHECK: store i8* [[ID]], i8**
+  // CHECK: store ptr null, ptr
+  // CHECK: store ptr null, ptr
+  // CHECK: [[ID:%.*]] = call ptr @llvm.objc.retain(ptr
+  // CHECK: store ptr [[ID]], ptr
   id x[3] = {
     [2] = i
   };
@@ -1531,56 +1378,50 @@ void test70(id i) {
 
 // CHECK-LABEL: define{{.*}} void @test71
 void test71(void) {
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP1:[^ ]+]] to i8*
-  // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* %[[T]])
-  // CHECK: call void @getAggDtor(%struct.AggDtor* sret(%struct.AggDtor) align 8 %[[TMP1]])
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP1]] to i8**
-  // CHECK: call void @__destructor_8_s40(i8** %[[T]])
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP1:[^ ]+]] to i8*
-  // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* %[[T]])
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP2:[^ ]+]] to i8*
-  // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* %[[T]])
-  // CHECK: call void @getAggDtor(%struct.AggDtor* sret(%struct.AggDtor) align 8 %[[TMP2]])
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP2]] to i8**
-  // CHECK: call void @__destructor_8_s40(i8** %[[T]])
-  // CHECK: %[[T:[^ ]+]] = bitcast %struct.AggDtor* %[[TMP2:[^ ]+]] to i8*
-  // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* %[[T]])
+  // CHECK: call void @llvm.lifetime.start.p0({{[^,]+}}, ptr %[[T:.*]])
+  // CHECK: call void @getAggDtor(ptr sret(%struct.AggDtor) align 8 %[[T]])
+  // CHECK: call void @__destructor_8_s40(ptr %[[T]])
+  // CHECK: call void @llvm.lifetime.end.p0({{[^,]+}}, ptr %[[T]])
+  // CHECK: call void @llvm.lifetime.start.p0({{[^,]+}}, ptr %[[T2:.*]])
+  // CHECK: call void @getAggDtor(ptr sret(%struct.AggDtor) align 8 %[[T2]])
+  // CHECK: call void @__destructor_8_s40(ptr %[[T2]])
+  // CHECK: call void @llvm.lifetime.end.p0({{[^,]+}}, ptr %[[T2]])
   getAggDtor();
   getAggDtor();
 }
 
 // Check that no extra release calls are emitted to detruct the compond literal.
 
-// CHECK: define{{.*}} void @test72(i8* noundef %[[A:.*]], i8* noundef %[[B:.*]])
-// CHECK: %[[A_ADDR:.*]] = alloca i8*, align 8
-// CHECK: %[[B_ADDR:.*]] = alloca i8*, align 8
-// CHECK: %[[T:.*]] = alloca [2 x i8*], align 16
-// CHECK: %[[V0:.*]] = call i8* @llvm.objc.retain(i8* %[[A]])
-// CHECK: %[[V1:.*]] = call i8* @llvm.objc.retain(i8* %[[B]]) #2
-// CHECK: %[[ARRAYINIT_BEGIN:.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %[[T]], i64 0, i64 0
-// CHECK: %[[V3:.*]] = load i8*, i8** %[[A_ADDR]], align 8, !tbaa !7
-// CHECK: %[[V4:.*]] = call i8* @llvm.objc.retain(i8* %[[V3]]) #2
-// CHECK: store i8* %[[V4]], i8** %[[ARRAYINIT_BEGIN]], align 8, !tbaa !7
-// CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds i8*, i8** %[[ARRAYINIT_BEGIN]], i64 1
-// CHECK: %[[V5:.*]] = load i8*, i8** %[[B_ADDR]], align 8, !tbaa !7
-// CHECK: %[[V6:.*]] = call i8* @llvm.objc.retain(i8* %[[V5]]) #2
-// CHECK: store i8* %[[V6]], i8** %[[ARRAYINIT_ELEMENT]], align 8, !tbaa !7
-// CHECK: %[[ARRAY_BEGIN:.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %[[T]], i32 0, i32 0
-// CHECK: %[[V7:.*]] = getelementptr inbounds i8*, i8** %[[ARRAY_BEGIN]], i64 2
+// CHECK: define{{.*}} void @test72(ptr noundef %[[A:.*]], ptr noundef %[[B:.*]])
+// CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8
+// CHECK: %[[B_ADDR:.*]] = alloca ptr, align 8
+// CHECK: %[[T:.*]] = alloca [2 x ptr], align 16
+// CHECK: %[[V0:.*]] = call ptr @llvm.objc.retain(ptr %[[A]])
+// CHECK: %[[V1:.*]] = call ptr @llvm.objc.retain(ptr %[[B]]) #2
+// CHECK: %[[ARRAYINIT_BEGIN:.*]] = getelementptr inbounds [2 x ptr], ptr %[[T]], i64 0, i64 0
+// CHECK: %[[V3:.*]] = load ptr, ptr %[[A_ADDR]], align 8, !tbaa !7
+// CHECK: %[[V4:.*]] = call ptr @llvm.objc.retain(ptr %[[V3]]) #2
+// CHECK: store ptr %[[V4]], ptr %[[ARRAYINIT_BEGIN]], align 8, !tbaa !7
+// CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds ptr, ptr %[[ARRAYINIT_BEGIN]], i64 1
+// CHECK: %[[V5:.*]] = load ptr, ptr %[[B_ADDR]], align 8, !tbaa !7
+// CHECK: %[[V6:.*]] = call ptr @llvm.objc.retain(ptr %[[V5]]) #2
+// CHECK: store ptr %[[V6]], ptr %[[ARRAYINIT_ELEMENT]], align 8, !tbaa !7
+// CHECK: %[[ARRAY_BEGIN:.*]] = getelementptr inbounds [2 x ptr], ptr %[[T]], i32 0, i32 0
+// CHECK: %[[V7:.*]] = getelementptr inbounds ptr, ptr %[[ARRAY_BEGIN]], i64 2
 
 // CHECK-NOT: call void @llvm.objc.release
 
-// CHECK: %[[ARRAYDESTROY_ELEMENTPAST:.*]] = phi i8** [ %[[V7]], %{{.*}} ], [ %[[ARRAYDESTROY_ELEMENT:.*]], %{{.*}} ]
-// CHECK: %[[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds i8*, i8** %[[ARRAYDESTROY_ELEMENTPAST]], i64 -1
-// CHECK: %[[V8:.*]] = load i8*, i8** %[[ARRAYDESTROY_ELEMENT]], align 8
-// CHECK: call void @llvm.objc.release(i8* %[[V8]]) #2, !clang.imprecise_release !10
+// CHECK: %[[ARRAYDESTROY_ELEMENTPAST:.*]] = phi ptr [ %[[V7]], %{{.*}} ], [ %[[ARRAYDESTROY_ELEMENT:.*]], %{{.*}} ]
+// CHECK: %[[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds ptr, ptr %[[ARRAYDESTROY_ELEMENTPAST]], i64 -1
+// CHECK: %[[V8:.*]] = load ptr, ptr %[[ARRAYDESTROY_ELEMENT]], align 8
+// CHECK: call void @llvm.objc.release(ptr %[[V8]]) #2, !clang.imprecise_release !10
 
 // CHECK-NOT: call void @llvm.objc.release
 
-// CHECK: %[[V10:.*]] = load i8*, i8** %[[B_ADDR]], align 8
-// CHECK: call void @llvm.objc.release(i8* %[[V10]]) #2, !clang.imprecise_release !10
-// CHECK: %[[V11:.*]] = load i8*, i8** %[[A_ADDR]], align 8
-// CHECK: call void @llvm.objc.release(i8* %[[V11]]) #2, !clang.imprecise_release !10
+// CHECK: %[[V10:.*]] = load ptr, ptr %[[B_ADDR]], align 8
+// CHECK: call void @llvm.objc.release(ptr %[[V10]]) #2, !clang.imprecise_release !10
+// CHECK: %[[V11:.*]] = load ptr, ptr %[[A_ADDR]], align 8
+// CHECK: call void @llvm.objc.release(ptr %[[V11]]) #2, !clang.imprecise_release !10
 
 void test72(id a, id b) {
   __strong id t[] = (__strong id[]){a, b};

diff  --git a/clang/test/CodeGenObjC/block-6.m b/clang/test/CodeGenObjC/block-6.m
index 2b95154f2d706..30dafa5b3cb91 100644
--- a/clang/test/CodeGenObjC/block-6.m
+++ b/clang/test/CodeGenObjC/block-6.m
@@ -1,18 +1,18 @@
-// RUN: %clang_cc1 -no-opaque-pointers %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 | FileCheck %s
 // rdar://8893785
 
 void MYFUNC(void) {
 // CHECK-LABEL:    define{{.*}} void @MYFUNC()
 // CHECK:      [[OBSERVER_SLOT:%.*]] = alloca [[OBSERVER_T:%.*]], align 8
+// CHECK:      [[BLOCK:%.*]] = alloca <{
 
-// CHECK:      [[T0:%.*]] = getelementptr inbounds [[OBSERVER_T]], [[OBSERVER_T]]* [[OBSERVER_SLOT]], i32 0, i32 1
-// CHECK:      store [[OBSERVER_T]]* [[OBSERVER_SLOT]], [[OBSERVER_T]]** [[T0]]
+// CHECK:      [[T0:%.*]] = getelementptr inbounds [[OBSERVER_T]], ptr [[OBSERVER_SLOT]], i32 0, i32 1
+// CHECK:      store ptr [[OBSERVER_SLOT]], ptr [[T0]]
 
-// CHECK:      [[T1:%.*]] = bitcast i8* ()*
-// CHECK:      [[FORWARDING:%.*]] = getelementptr inbounds [[OBSERVER_T]], [[OBSERVER_T]]* [[OBSERVER_SLOT]], i32 0, i32 1
-// CHECK-NEXT: [[T0:%.*]] = load [[OBSERVER_T]]*, [[OBSERVER_T]]** [[FORWARDING]]
-// CHECK-NEXT: [[OBSERVER:%.*]] = getelementptr inbounds [[OBSERVER_T]], [[OBSERVER_T]]* [[T0]], i32 0, i32 6
-// CHECK-NEXT: store i8* [[T1]], i8** [[OBSERVER]]
+// CHECK:      [[FORWARDING:%.*]] = getelementptr inbounds [[OBSERVER_T]], ptr [[OBSERVER_SLOT]], i32 0, i32 1
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[FORWARDING]]
+// CHECK-NEXT: [[OBSERVER:%.*]] = getelementptr inbounds [[OBSERVER_T]], ptr [[T0]], i32 0, i32 6
+// CHECK-NEXT: store ptr [[BLOCK]], ptr [[OBSERVER]]
   __block id observer = ^{ return observer; };
 }
 

diff  --git a/clang/test/CodeGenObjC/block-desc-str.m b/clang/test/CodeGenObjC/block-desc-str.m
index 6f242c0603f6f..1472476f5985b 100644
--- a/clang/test/CodeGenObjC/block-desc-str.m
+++ b/clang/test/CodeGenObjC/block-desc-str.m
@@ -1,15 +1,15 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-freebsd -emit-llvm -fobjc-runtime=gnustep-1.7 -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple=x86_64-apple-darwin10 -emit-llvm -fblocks -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -emit-llvm -fobjc-runtime=gnustep-1.7 -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fblocks -o - %s | FileCheck %s
 
 // Test that descriptor symbol names don't include '@'.
 
 // CHECK-COMDAT: $"__block_descriptor_40_8_32o_e5_v8\01?0l" = comdat any
 // CHECK-COMDAT: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v8@?0\00"
-// CHECK-COMDAT: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, {{.*}} } { i64 0, i64 40, i8* bitcast ({{.*}} to i8*), i8* bitcast ({{.*}} to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @[[STR]], i32 0, i32 0), {{.*}} }, comdat, align 8
+// CHECK-COMDAT: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, {{.*}} } { i64 0, i64 40, ptr {{.*}}, ptr @[[STR]], {{.*}} }, comdat, align 8
 
 // CHECK: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v8@?0\00"
-// CHECK: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, {{.*}} } { i64 0, i64 40, i8* bitcast ({{.*}} to i8*), i8* bitcast ({{.*}} to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @[[STR]], i32 0, i32 0), {{.*}} }, align 8
+// CHECK: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr, ptr, {{.*}} } { i64 0, i64 40, ptr {{.*}}, ptr {{.*}}, ptr @[[STR]], {{.*}} }, align 8
 
 typedef void (^BlockTy)(void);
 

diff  --git a/clang/test/CodeGenObjC/blocks.m b/clang/test/CodeGenObjC/blocks.m
index e20201c53590d..62b046ebd5ecf 100644
--- a/clang/test/CodeGenObjC/blocks.m
+++ b/clang/test/CodeGenObjC/blocks.m
@@ -1,11 +1,9 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck %s
-
-// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i32, i32 }
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck %s
 
 // Check that there is only one capture (20o) in the copy/dispose function
 // names.
 
-// CHECK: @[[BLOCK_DESCRIPTOR0:.*]] = linkonce_odr hidden unnamed_addr constant { i32, i32, i8*, i8*, i8*, i32 } { i32 0, i32 28, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_4_20o to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_4_20o to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i32 512 },
+// CHECK: @[[BLOCK_DESCRIPTOR0:.*]] = linkonce_odr hidden unnamed_addr constant { i32, i32, ptr, ptr, ptr, i32 } { i32 0, i32 28, ptr @__copy_helper_block_4_20o, ptr @__destroy_helper_block_4_20o, ptr @{{.*}}, i32 512 },
 
 void (^gb0)(void);
 
@@ -53,44 +51,43 @@ @interface Test2 -(void) destroy; @end
 void test2(Test2 *x) {
   extern void test2_helper(void (^)(void));
   // CHECK-LABEL:    define{{.*}} void @test2(
-  // CHECK:      [[X:%.*]] = alloca [[TEST2:%.*]]*,
+  // CHECK:      [[X:%.*]] = alloca ptr,
   // CHECK-NEXT: [[WEAKX:%.*]] = alloca [[WEAK_T:%.*]],
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-  // CHECK-NEXT: store [[TEST2]]*
+  // CHECK-NEXT: store ptr
 
   // isa=1 for weak byrefs.
-  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 0
-  // CHECK-NEXT: store i8* inttoptr (i32 1 to i8*), i8** [[T0]]
+  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 0
+  // CHECK-NEXT: store ptr inttoptr (i32 1 to ptr), ptr [[T0]]
 
   // Forwarding.
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 1
-  // CHECK-NEXT: store [[WEAK_T]]* [[WEAKX]], [[WEAK_T]]** [[T1]]
+  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 1
+  // CHECK-NEXT: store ptr [[WEAKX]], ptr [[T1]]
 
   // Flags.  This is just BLOCK_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_UNRETAINED
-  // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 2
-  // CHECK-NEXT: store i32 1375731712, i32* [[T2]]
+  // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 2
+  // CHECK-NEXT: store i32 1375731712, ptr [[T2]]
 
   // Size.
-  // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 3
-  // CHECK-NEXT: store i32 28, i32* [[T3]]
+  // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 3
+  // CHECK-NEXT: store i32 28, ptr [[T3]]
 
   // Copy and dispose helpers.
-  // CHECK-NEXT: [[T4:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 4
-  // CHECK-NEXT: store i8* bitcast (void (i8*, i8*)* @__Block_byref_object_copy_{{.*}} to i8*), i8** [[T4]]
-  // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 5
-  // CHECK-NEXT: store i8* bitcast (void (i8*)* @__Block_byref_object_dispose_{{.*}} to i8*), i8** [[T5]]
+  // CHECK-NEXT: [[T4:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 4
+  // CHECK-NEXT: store ptr @__Block_byref_object_copy_{{.*}}, ptr [[T4]]
+  // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 5
+  // CHECK-NEXT: store ptr @__Block_byref_object_dispose_{{.*}}, ptr [[T5]]
 
   // Actually capture the value.
-  // CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 6
-  // CHECK-NEXT: [[CAPTURE:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]]
-  // CHECK-NEXT: store [[TEST2]]* [[CAPTURE]], [[TEST2]]** [[T6]]
+  // CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds [[WEAK_T]], ptr [[WEAKX]], i32 0, i32 6
+  // CHECK-NEXT: [[CAPTURE:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NEXT: store ptr [[CAPTURE]], ptr [[T6]]
 
   // Then we initialize the block, blah blah blah.
   // CHECK:      call void @test2_helper(
 
   // Finally, kill the variable with BLOCK_FIELD_IS_BYREF.
-  // CHECK:      [[T0:%.*]] = bitcast [[WEAK_T]]* [[WEAKX]] to i8*
-  // CHECK:      call void @_Block_object_dispose(i8* [[T0]], i32 24)
+  // CHECK:      call void @_Block_object_dispose(ptr [[WEAKX]], i32 24)
 
   __attribute__((objc_gc(weak))) __block Test2 *weakX = x;
   test2_helper(^{ [weakX destroy]; });
@@ -100,15 +97,12 @@ void test2(Test2 *x) {
 // In the test above, check that the use in the invocation function
 // doesn't require a read barrier.
 // CHECK-LABEL:    define internal void @__test2_block_invoke
-// CHECK:      [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
-// CHECK-NOT:  bitcast
-// CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[WEAK_T]]{{.*}}*
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, [[WEAK_T]]{{.*}}* [[T2]], i32 0, i32 1
-// CHECK-NEXT: [[T4:%.*]] = load [[WEAK_T]]{{.*}}*, [[WEAK_T]]{{.*}}** [[T3]]
-// CHECK-NEXT: [[WEAKX:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, [[WEAK_T]]{{.*}}* [[T4]], i32 0, i32 6
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[WEAKX]], align 4
+// CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr {{%.*}}, i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[T0]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, ptr [[T1]], i32 0, i32 1
+// CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[T3]]
+// CHECK-NEXT: [[WEAKX:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, ptr [[T4]], i32 0, i32 6
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[WEAKX]], align 4
 
 // rdar://problem/12722954
 // Make sure that ... is appropriately positioned in a block call.
@@ -116,30 +110,24 @@ void test3(void (^block)(int, ...)) {
   block(0, 1, 2, 3);
 }
 // CHECK-LABEL:    define{{.*}} void @test3(
-// CHECK:      [[BLOCK:%.*]] = alloca void (i32, ...)*, align 4
-// CHECK-NEXT: store void (i32, ...)*
-// CHECK-NEXT: [[T0:%.*]] = load void (i32, ...)*, void (i32, ...)** [[BLOCK]], align 4
-// CHECK-NEXT: [[T1:%.*]] = bitcast void (i32, ...)* [[T0]] to [[BLOCK_T:%.*]]*
-// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 3
-// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
-// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T2]]
-// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, ...)*
-// CHECK-NEXT: call void (i8*, i32, ...) [[T5]](i8* noundef [[T3]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
+// CHECK:      [[BLOCK:%.*]] = alloca ptr, align 4
+// CHECK-NEXT: store ptr
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[BLOCK]], align 4
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T:%.*]], ptr [[T0]], i32 0, i32 3
+// CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[T2]]
+// CHECK-NEXT: call void (ptr, i32, ...) [[T4]](ptr noundef [[T0]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
 // CHECK-NEXT: ret void
 
 void test4(void (^block)()) {
   block(0, 1, 2, 3);
 }
 // CHECK-LABEL:    define{{.*}} void @test4(
-// CHECK:      [[BLOCK:%.*]] = alloca void (...)*, align 4
-// CHECK-NEXT: store void (...)*
-// CHECK-NEXT: [[T0:%.*]] = load void (...)*, void (...)** [[BLOCK]], align 4
-// CHECK-NEXT: [[T1:%.*]] = bitcast void (...)* [[T0]] to [[BLOCK_T:%.*]]*
-// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 3
-// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
-// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T2]]
-// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, i32, i32, i32)*
-// CHECK-NEXT: call void [[T5]](i8* noundef [[T3]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
+// CHECK:      [[BLOCK:%.*]] = alloca ptr, align 4
+// CHECK-NEXT: store ptr
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[BLOCK]], align 4
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T:%.*]], ptr [[T0]], i32 0, i32 3
+// CHECK-NEXT: [[T4:%.*]] = load ptr, ptr [[T2]]
+// CHECK-NEXT: call void [[T4]](ptr noundef [[T0]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
 // CHECK-NEXT: ret void
 
 void test5(A *a) {
@@ -148,8 +136,8 @@ void test5(A *a) {
 }
 
 // CHECK-LABEL: define void @test5(
-// CHECK: %[[V0:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, {{.*}}*, {{.*}}* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, {{.*}}*, {{.*}}* }>* %{{.*}}, i32 0, i32 4
-// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i32, i32, i8*, i8*, i8*, i32 }* @[[BLOCK_DESCRIPTOR0]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[V0]],
+// CHECK: %[[V0:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
+// CHECK: store ptr @[[BLOCK_DESCRIPTOR0]], ptr %[[V0]],
 
 void test6(id a, long long b) {
   void (^block)() = ^{ (void)b; (void)a; };
@@ -158,4 +146,4 @@ void test6(id a, long long b) {
 // Check that the block literal doesn't have two fields for capture 'a'.
 
 // CHECK-LABEL: define void @test6(
-// CHECK: alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i64 }>,
+// CHECK: alloca <{ ptr, i32, i32, ptr, ptr, ptr, i64 }>,

diff  --git a/clang/test/CodeGenObjC/boxing.m b/clang/test/CodeGenObjC/boxing.m
index cca8de051f214..3f857e089ded7 100644
--- a/clang/test/CodeGenObjC/boxing.m
+++ b/clang/test/CodeGenObjC/boxing.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
 
 typedef long NSInteger;
 typedef unsigned long NSUInteger;
@@ -53,53 +53,52 @@ @interface NSString (NSStringExtensionMethods)
 + (id)stringWithUTF8String:(const char *)nullTerminatedCString;
 @end
 
-// CHECK: [[V0:%.*]] = type opaque
-// CHECK: [[STRUCT_NSCONSTANT_STRING_TAG:%.*]] = type { i32*, i32, i8*, i64 }
+// CHECK: [[STRUCT_NSCONSTANT_STRING_TAG:%.*]] = type { ptr, i32, ptr, i64 }
 
 // CHECK: [[WithIntMeth:@.*]] = private unnamed_addr constant [15 x i8] c"numberWithInt:\00"
-// CHECK: [[WithIntSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[WithIntMeth]]
+// CHECK: [[WithIntSEL:@.*]] = internal externally_initialized global ptr [[WithIntMeth]]
 // CHECK: [[WithCharMeth:@.*]] = private unnamed_addr constant [16 x i8] c"numberWithChar:\00"
-// CHECK: [[WithCharSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[WithCharMeth]]
+// CHECK: [[WithCharSEL:@.*]] = internal externally_initialized global ptr [[WithCharMeth]]
 // CHECK: [[WithBoolMeth:@.*]] = private unnamed_addr constant [16 x i8] c"numberWithBool:\00"
-// CHECK: [[WithBoolSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[WithBoolMeth]]
+// CHECK: [[WithBoolSEL:@.*]] = internal externally_initialized global ptr [[WithBoolMeth]]
 // CHECK: [[WithIntegerMeth:@.*]] = private unnamed_addr constant [19 x i8] c"numberWithInteger:\00"
-// CHECK: [[WithIntegerSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[WithIntegerMeth]]
+// CHECK: [[WithIntegerSEL:@.*]] = internal externally_initialized global ptr [[WithIntegerMeth]]
 // CHECK: [[WithUnsignedIntegerMeth:@.*]] = private unnamed_addr constant [27 x i8] c"numberWithUnsignedInteger:\00"
-// CHECK: [[WithUnsignedIntegerSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([27 x i8], [27 x i8]* [[WithUnsignedIntegerMeth]]
+// CHECK: [[WithUnsignedIntegerSEL:@.*]] = internal externally_initialized global ptr [[WithUnsignedIntegerMeth]]
 // CHECK: [[stringWithUTF8StringMeth:@.*]] = private unnamed_addr constant [22 x i8] c"stringWithUTF8String:\00"
-// CHECK: [[stringWithUTF8StringSEL:@.*]] = internal externally_initialized global i8* getelementptr inbounds ([22 x i8], [22 x i8]* [[stringWithUTF8StringMeth]]
+// CHECK: [[stringWithUTF8StringSEL:@.*]] = internal externally_initialized global ptr [[stringWithUTF8StringMeth]]
 // CHECK: [[STR0:.*]] = private unnamed_addr constant [4 x i8] c"abc\00", section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: [[UNNAMED_CFSTRING:.*]] = private global [[STRUCT_NSCONSTANT_STRING_TAG]] { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR0]], i32 0, i32 0), i64 3 }, section "__DATA,__cfstring", align 8
+// CHECK: [[UNNAMED_CFSTRING:.*]] = private global [[STRUCT_NSCONSTANT_STRING_TAG]] { ptr @__CFConstantStringClassReference, i32 1992, ptr [[STR0]], i64 3 }, section "__DATA,__cfstring", align 8
 
 int main(void) {
-  // CHECK: [[T:%.*]] = alloca [[V0]]*, align 8
+  // CHECK: [[T:%t]] = alloca ptr, align 8
 
-  // CHECK: load i8*, i8** [[WithIntSEL]]
+  // CHECK: load ptr, ptr [[WithIntSEL]]
   int i; @(i);
-  // CHECK: load i8*, i8** [[WithCharSEL]]
+  // CHECK: load ptr, ptr [[WithCharSEL]]
   signed char sc; @(sc);
-  // CHECK: load i8*, i8** [[WithBoolSEL]]
+  // CHECK: load ptr, ptr [[WithBoolSEL]]
   BOOL b; @(b);
-  // CHECK: load i8*, i8** [[WithBoolSEL]]
+  // CHECK: load ptr, ptr [[WithBoolSEL]]
   typeof(b) b2; @(b2);
-  // CHECK: load i8*, i8** [[WithBoolSEL]]
+  // CHECK: load ptr, ptr [[WithBoolSEL]]
   typedef const typeof(b) MyBOOL; MyBOOL b3; @(b3);
-  // CHECK: load i8*, i8** [[WithBoolSEL]]
+  // CHECK: load ptr, ptr [[WithBoolSEL]]
   @((BOOL)i);
-  // CHECK: load i8*, i8** [[WithIntegerSEL]]
+  // CHECK: load ptr, ptr [[WithIntegerSEL]]
   @((NSInteger)i);
-  // CHECK: load i8*, i8** [[WithUnsignedIntegerSEL]]
+  // CHECK: load ptr, ptr [[WithUnsignedIntegerSEL]]
   @((NSUInteger)i);
-  // CHECK: load i8*, i8** [[stringWithUTF8StringSEL]]
+  // CHECK: load ptr, ptr [[stringWithUTF8StringSEL]]
   const char *s; @(s);
 
   typedef enum : NSInteger { Red, Green, Blue } Color;
-  // CHECK: load i8*, i8** [[WithIntegerSEL]]
+  // CHECK: load ptr, ptr [[WithIntegerSEL]]
   @(Red);
   Color col = Red;
-  // CHECK: load i8*, i8** [[WithIntegerSEL]]
+  // CHECK: load ptr, ptr [[WithIntegerSEL]]
   @(col);
 
-  // CHECK: store [[V0]]* bitcast ([[STRUCT_NSCONSTANT_STRING_TAG]]* [[UNNAMED_CFSTRING]] to [[V0]]*), [[V0]]** [[T]], align 8
+  // CHECK: store ptr [[UNNAMED_CFSTRING]], ptr [[T]], align 8
   NSString *t = @("abc");
 }

diff  --git a/clang/test/CodeGenObjC/debug-info-block-line.m b/clang/test/CodeGenObjC/debug-info-block-line.m
index 8acf56ab447a7..2ad9a5aa6e638 100644
--- a/clang/test/CodeGenObjC/debug-info-block-line.m
+++ b/clang/test/CodeGenObjC/debug-info-block-line.m
@@ -1,5 +1,5 @@
 // REQUIRES: x86-registered-target
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -fblocks -fobjc-arc -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
 
 // rdar://11562117
 typedef unsigned int NSUInteger;
@@ -62,16 +62,13 @@ - (void)serverConnection:(TConnection *)connection getCommand:(NSString *)str
     TMap       *map = [TMap mapForID:mapID];
 // Make sure we do not map code generated for the block to the above line.
 // CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke"
-// CHECK: call void @llvm.objc.storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]]
-// CHECK: call void @llvm.objc.storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]]
+// CHECK: call void @llvm.objc.storeStrong(ptr [[CONNECTION_ADDR:%.*]], ptr [[ONE:%.*]]) [[NUW:#[0-9]+]]
+// CHECK: call void @llvm.objc.storeStrong(ptr [[STR_ADDR:%.*]], ptr [[THREE:%.*]]) [[NUW]]
 // CHECK: call {{.*}}@objc_msgSend{{.*}}, !dbg ![[LINE_ABOVE:[0-9]+]]
 // CHECK: getelementptr
 // CHECK-NOT: !dbg, ![[LINE_ABOVE]]
-// CHECK: bitcast %5** [[TMP:%.*]] to i8**
-// CHECK-NOT: !dbg, ![[LINE_ABOVE]]
-// CHECK: call void @llvm.objc.storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]]
-// CHECK-NEXT: bitcast %4** [[TMP:%.*]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]]
+// CHECK: call void @llvm.objc.storeStrong(ptr [[STR_ADDR]], ptr null) [[NUW]]
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[CONNECTION_ADDR]], ptr null) [[NUW]]
 // CHECK-NEXT: ret
 // CHECK: attributes [[NUW]] = { nounwind }
     [map dataWithCompletionBlock:^(NSData *data, NSError *error) {

diff  --git a/clang/test/CodeGenObjC/debug-info-blocks.m b/clang/test/CodeGenObjC/debug-info-blocks.m
index 5184f966bb200..ec6bbe36f16a7 100644
--- a/clang/test/CodeGenObjC/debug-info-blocks.m
+++ b/clang/test/CodeGenObjC/debug-info-blocks.m
@@ -1,25 +1,24 @@
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -fblocks -debug-info-kind=limited  -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -x objective-c < %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fblocks -debug-info-kind=limited  -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -x objective-c < %s -o - | FileCheck %s
 
 // rdar://problem/9279956
 // Test that we generate the proper debug location for a captured self.
 // The second half of this test is in llvm/tests/DebugInfo/debug-info-blocks.ll
 
 // CHECK: define {{.*}}_block_invoke
-// CHECK: %[[BLOCK:.*]] = bitcast i8* %.block_descriptor to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>*, !dbg
-// CHECK-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA:.*]], align
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
+// CHECK: store ptr %.block_descriptor, ptr %[[ALLOCA:block.addr]], align
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
 
 // Test that we do emit scope info for the helper functions, and that the
 // parameters to these functions are marked as artificial (so the debugger
 // doesn't accidentally step into the function).
-// CHECK: define {{.*}} @__copy_helper_block_{{.*}}(i8* noundef %0, i8* noundef %1)
+// CHECK: define {{.*}} @__copy_helper_block_{{.*}}(ptr noundef %0, ptr noundef %1)
 // CHECK-NOT: ret
 // CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DBG_LINE]]
 // CHECK: ret {{.*}}, !dbg ![[DBG_LINE]]
-// CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*
+// CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(ptr
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
 // CHECK: ret {{.*}}, !dbg ![[DESTROY_LINE]]

diff  --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m
index 5d317f470493a..8a3c2f575d2d3 100644
--- a/clang/test/CodeGenObjC/direct-method.m
+++ b/clang/test/CodeGenObjC/direct-method.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
 
 struct my_complex_struct {
   int a, b;
@@ -28,18 +28,17 @@ - (int)getInt __attribute__((objc_direct)) {
   // loading parameters
   // CHECK-LABEL: entry:
   // CHECK-NEXT: [[RETVAL:%.*]] = alloca
-  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
-  // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
+  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
 
   // self nil-check
-  // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
-  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
+  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
   // CHECK-NEXT: br i1 [[NILCHECK]],
 
   // setting return value to nil
   // CHECK-LABEL: objc_direct_method.self_is_nil:
-  // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
-  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
   // CHECK-NEXT: br label
 
   // set value
@@ -58,14 +57,14 @@ - (int)getInt __attribute__((objc_direct)) {
 + (int)classGetInt __attribute__((objc_direct)) {
   // loading parameters
   // CHECK-LABEL: entry:
-  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca i8*,
-  // CHECK-NEXT: store i8* %{{.*}}, i8** [[SELFADDR]],
+  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
+  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
 
   // [self self]
-  // CHECK-NEXT: [[SELF:%.*]] = load i8*, i8** [[SELFADDR]],
-  // CHECK-NEXT: [[SELFSEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
+  // CHECK-NEXT: [[SELFSEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
   // CHECK-NEXT: [[SELF0:%.*]] = call {{.*}} @objc_msgSend
-  // CHECK-NEXT: store i8* [[SELF0]], i8** [[SELFADDR]],
+  // CHECK-NEXT: store ptr [[SELF0]], ptr [[SELFADDR]],
 
   // return
   // CHECK-NEXT: ret
@@ -77,30 +76,27 @@ - (struct my_complex_struct)getComplex __attribute__((objc_direct)) {
   // loading parameters
   // CHECK-LABEL: entry:
   // CHECK-NEXT: [[RETVAL:%.*]] = alloca
-  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
-  // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
+  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
 
   // self nil-check
-  // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
-  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
+  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
   // CHECK-NEXT: br i1 [[NILCHECK]],
 
   // setting return value to nil
   // CHECK-LABEL: objc_direct_method.self_is_nil:
-  // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
-  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
   // CHECK-NEXT: br label
 
   // set value
   // CHECK-LABEL: objc_direct_method.cont:
-  // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]]
-  // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RET1]],
+  // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RETVAL]],
   // CHECK-NEXT: br label
 
   // return
   // CHECK-LABEL: return:
-  // CHECK: [[RET2:%.*]] = bitcast{{.*}}[[RETVAL]]
-  // CHECK-NEXT: {{%.*}} = load{{.*}}[[RET2]],
+  // CHECK-NEXT: {{%.*}} = load{{.*}}[[RETVAL]],
   // CHECK-NEXT: ret
   struct my_complex_struct st = {.a = 42};
   return st;
@@ -115,27 +111,25 @@ + (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) {
 
 // CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"(
 - (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) {
-  // CHECK: %struct.my_aggregate_struct* noalias sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]],
+  // CHECK: ptr noalias sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]],
 
   // loading parameters
   // CHECK-LABEL: entry:
-  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
-  // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
+  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],
 
   // self nil-check
-  // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
-  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],
+  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null
   // CHECK-NEXT: br i1 [[NILCHECK]],
 
   // setting return value to nil
   // CHECK-LABEL: objc_direct_method.self_is_nil:
-  // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
-  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,
   // CHECK-NEXT: br label
 
   // set value
   // CHECK-LABEL: objc_direct_method.cont:
-  // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]]
   // CHECK: br label
 
   // return
@@ -155,13 +149,13 @@ + (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {
 // CHECK-LABEL: define hidden void @"\01-[Root accessCmd]"(
 - (void)accessCmd __attribute__((objc_direct)) {
   // CHECK-LABEL: entry:
-  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
-  // CHECK-NEXT: [[CMDVAL:%_cmd]] = alloca i8*,
+  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,
+  // CHECK-NEXT: [[CMDVAL:%_cmd]] = alloca ptr,
 
   // loading the _cmd selector
   // CHECK-LABEL: objc_direct_method.cont:
-  // CHECK-NEXT: [[CMD1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
-  // CHECK-NEXT: store i8* [[CMD1]], i8** [[CMDVAL]],
+  // CHECK-NEXT: [[CMD1:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+  // CHECK-NEXT: store ptr [[CMD1]], ptr [[CMDVAL]],
   SEL sel = _cmd;
 }
 
@@ -170,12 +164,11 @@ - (void)accessCmd __attribute__((objc_direct)) {
 
 // Check the synthesized objectProperty calls objc_getProperty(); this also
 // checks that the synthesized method passes undef for the `cmd` argument.
-// CHECK-LABEL: define hidden i8* @"\01-[Root objectProperty]"(
+// CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(
 // CHECK-LABEL: objc_direct_method.cont:
 // CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,
-// CHECK-NEXT: [[SELF:%.*]] = bitcast {{.*}} [[SELFVAL]] to i8*
 // CHECK-NEXT: [[IVAR:%.*]] = load {{.*}} @"OBJC_IVAR_$_Root._objectProperty",
-// CHECK-NEXT: call i8* @objc_getProperty(i8* noundef [[SELF]], i8* noundef poison, i64 noundef [[IVAR]], {{.*}})
+// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef [[IVAR]], {{.*}})
 
 @interface Foo : Root {
   id __strong _cause_cxx_destruct;
@@ -220,19 +213,19 @@ - (int)directMethodInCategoryNoDecl __attribute__((objc_direct)) {
 
 int useRoot(Root *r) {
   // CHECK-LABEL: define{{.*}} i32 @useRoot
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]" to i32 (i8*)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]" to i32 (i8*)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]" to i32 (i8*)
+  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root getInt]"
+  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty]"
+  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty2]"
   return [r getInt] + [r intProperty] + [r intProperty2];
 }
 
 int useFoo(Foo *f) {
   // CHECK-LABEL: define{{.*}} i32 @useFoo
-  // CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]" to void (i8*, i32)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]" to i32 (i8*)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInExtension]" to i32 (i8*)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategory]" to i32 (i8*)
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategoryNoDecl]" to i32 (i8*)
+  // CHECK: call void @"\01-[Foo setGetDynamic_setDirect:]"
+  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo getDirect_setDynamic]"
+  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInExtension]"
+  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategory]"
+  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategoryNoDecl]"
   [f setGetDynamic_setDirect:1];
   return [f getDirect_setDynamic] +
          [f directMethodInExtension] +
@@ -247,6 +240,6 @@ @interface RootDeclOnly
 
 int useRootDeclOnly(RootDeclOnly *r) {
   // CHECK-LABEL: define{{.*}} i32 @useRootDeclOnly
-  // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[RootDeclOnly intProperty]"
+  // CHECK: %{{[^ ]*}} = call i32 @"\01-[RootDeclOnly intProperty]"
   return [r intProperty];
 }

diff  --git a/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m b/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m
index b9fc3d3217dd6..70b4ae05cf421 100644
--- a/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m
+++ b/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin -fblocks -fno-escaping-block-tail-calls -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -fno-escaping-block-tail-calls -emit-llvm -o - %s | FileCheck %s
 
 // CHECK-LABEL: define{{.*}} void @test(
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE0:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE1:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE2:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE3:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE4:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE5:.*]] to i8*)
-// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE6:.*]] to i8*)
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE0:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE1:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE2:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE3:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE4:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE5:.*invoke.*]], ptr
+// CHECK: store ptr @[[TEST_BLOCK_INVOKE6:.*invoke.*]], ptr
 
 // CHECK: define internal void @[[TEST_BLOCK_INVOKE0]]({{.*}}) #[[DISABLEATTR:.*]] {
 // CHECK: define internal void @[[TEST_BLOCK_INVOKE1]]({{.*}}) #[[ENABLEATTR:.*]] {

diff  --git a/clang/test/CodeGenObjC/externally-retained.m b/clang/test/CodeGenObjC/externally-retained.m
index 97cabd42d6385..0c0085e169ab4 100644
--- a/clang/test/CodeGenObjC/externally-retained.m
+++ b/clang/test/CodeGenObjC/externally-retained.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 -xobjective-c++ -std=c++11 %s -S -emit-llvm -o - | FileCheck %s --check-prefix CHECKXX
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 -xobjective-c++ -std=c++11 %s -S -emit-llvm -o - | FileCheck %s --check-prefix CHECKXX
 
 #define EXT_RET __attribute__((objc_externally_retained))
 
@@ -45,8 +45,7 @@ void in_init(void) {
   // CHECK-NEXT: [[GLOBAL:%.*]] = load {{.*}} @global
   // CHECK-NEXT: [[WAT_LOAD:%.*]] = load {{.*}} [[WAT]]
   // CHECK-NEXT: store {{.*}} [[GLOBAL]], {{.*}} [[WAT]]
-  // CHECK-NEXT: [[CASTED:%.*]] = bitcast {{.*}} [[WAT_LOAD]] to
-  // CHECK-NEXT: call void @llvm.objc.release(i8* [[CASTED]])
+  // CHECK-NEXT: call void @llvm.objc.release(ptr [[WAT_LOAD]])
 
   // CHECK-NOT: llvm.objc.
   // CHECK: ret
@@ -59,7 +58,7 @@ void block_capture(ObjTy *obj) EXT_RET {
 
   // CHECK-LABEL: define{{.*}} void @block_capture
   // CHECK-NOT: llvm.objc.
-  // CHECK: call i8* @llvm.objc.retain
+  // CHECK: call ptr @llvm.objc.retain
   // CHECK-NOT: llvm.objc.
   // CHECK: call void @esc
   // CHECK-NOT: llvm.objc.

diff  --git a/clang/test/CodeGenObjC/for-in.m b/clang/test/CodeGenObjC/for-in.m
index 2d0d10ce2cda3..9f3943f3ae0be 100644
--- a/clang/test/CodeGenObjC/for-in.m
+++ b/clang/test/CodeGenObjC/for-in.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers %s -verify -o /dev/null
-// RUN: %clang_cc1 -no-opaque-pointers %s -triple x86_64-apple-darwin -emit-llvm -fsanitize=objc-cast -o - | FileCheck %s
+// RUN: %clang_cc1 %s -verify -o /dev/null
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -emit-llvm -fsanitize=objc-cast -o - | FileCheck %s
 
 void p(const char*, ...);
 
@@ -27,17 +27,15 @@ void t0(void) {
   unsigned index = 0;
   for (NSString *i in array) {	// expected-warning {{collection expression type 'NSArray *' may not respond}}
 
-    // CHECK:      [[expectedCls:%.*]] = load %struct._class_t*, {{.*}}, !nosanitize
-    // CHECK-NEXT: [[kindOfClassSel:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES{{.*}}, !nosanitize
-    // CHECK-NEXT: [[expectedClsI8:%.*]] = bitcast %struct._class_t* [[expectedCls]] to i8*, !nosanitize
-    // CHECK-NEXT: [[isCls:%.*]] = call zeroext i1 bitcast {{.*}}@objc_msgSend to i1 (i8*, i8*, {{.*}})(i8* noundef [[theItem:%.*]], i8* noundef [[kindOfClassSel]], i8* noundef [[expectedClsI8]]), !nosanitize
+    // CHECK:      [[expectedCls:%.*]] = load ptr, {{.*}}, !nosanitize
+    // CHECK-NEXT: [[kindOfClassSel:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES{{.*}}, !nosanitize
+    // CHECK-NEXT: [[isCls:%.*]] = call zeroext i1 @objc_msgSend(ptr noundef [[theItem:%.*]], ptr noundef [[kindOfClassSel]], ptr noundef [[expectedCls]]), !nosanitize
     // CHECK: br i1 [[isCls]]
 
-    // CHECK: ptrtoint i8* [[theItem]] to i64, !nosanitize
+    // CHECK: ptrtoint ptr [[theItem]] to i64, !nosanitize
     // CHECK-NEXT: call void @__ubsan_handle_invalid_objc_cast
     // CHECK-NEXT: unreachable, !nosanitize
 
-    // CHECK: bitcast i8* [[theItem]]
 
     p("element %d: %s\n", index++, [i cString]);
   }

diff  --git a/clang/test/CodeGenObjC/fp2ret.m b/clang/test/CodeGenObjC/fp2ret.m
index b1051598d4422..51a771c27a3b1 100644
--- a/clang/test/CodeGenObjC/fp2ret.m
+++ b/clang/test/CodeGenObjC/fp2ret.m
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-X86_32 %s
 //
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-X86_64 %s
 //
-// RUN: %clang_cc1 -no-opaque-pointers -triple armv7-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -target-abi apcs-gnu -o - %s | \
+// RUN: %clang_cc1 -triple armv7-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -target-abi apcs-gnu -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-ARMV7 %s
 
 @interface A
@@ -13,15 +13,15 @@ -(_Complex long double) complexLongDoubleValue;
 
 
 // CHECK-X86_32-LABEL: define{{.*}} void @t0()
-// CHECK-X86_32: call void bitcast {{.*}} @objc_msgSend_stret to
+// CHECK-X86_32: call void @objc_msgSend_stret
 // CHECK-X86_32: }
 //
 // CHECK-X86_64-LABEL: define{{.*}} void @t0()
-// CHECK-X86_64: call { x86_fp80, x86_fp80 } bitcast {{.*}} @objc_msgSend_fp2ret to
+// CHECK-X86_64: call { x86_fp80, x86_fp80 } @objc_msgSend_fp2ret
 // CHECK-X86_64: }
 //
 // CHECK-ARMV7-LABEL: define{{.*}} void @t0()
-// CHECK-ARMV7: call i128 bitcast {{.*}} @objc_msgSend to
+// CHECK-ARMV7: call i128 @objc_msgSend
 // CHECK-ARMV7: }
 void t0(void) {
   [(A*)0 complexLongDoubleValue];

diff  --git a/clang/test/CodeGenObjC/fpret.m b/clang/test/CodeGenObjC/fpret.m
index 1e47acdd37ee0..f6751af61026f 100644
--- a/clang/test/CodeGenObjC/fpret.m
+++ b/clang/test/CodeGenObjC/fpret.m
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-X86_32 %s
 //
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-X86_64 %s
 //
-// RUN: %clang_cc1 -no-opaque-pointers -triple armv7-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -target-abi apcs-gnu -o - %s | \
+// RUN: %clang_cc1 -triple armv7-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -target-abi apcs-gnu -o - %s | \
 // RUN:   FileCheck --check-prefix=CHECK-ARMV7 %s
 
 @interface A
@@ -15,21 +15,21 @@ -(long double) longDoubleValue;
 
 
 // CHECK-X86_32-LABEL: define{{.*}} void @t0()
-// CHECK-X86_32: call float bitcast {{.*}} @objc_msgSend_fpret to
-// CHECK-X86_32: call double bitcast {{.*}} @objc_msgSend_fpret to
-// CHECK-X86_32: call x86_fp80 bitcast {{.*}} @objc_msgSend_fpret to
+// CHECK-X86_32: call float @objc_msgSend_fpret
+// CHECK-X86_32: call double @objc_msgSend_fpret
+// CHECK-X86_32: call x86_fp80 @objc_msgSend_fpret
 // CHECK-X86_32: }
 //
 // CHECK-X86_64-LABEL: define{{.*}} void @t0()
-// CHECK-X86_64: call float bitcast {{.*}} @objc_msgSend to
-// CHECK-X86_64: call double bitcast {{.*}} @objc_msgSend to
-// CHECK-X86_64: call x86_fp80 bitcast {{.*}} @objc_msgSend_fpret to
+// CHECK-X86_64: call float @objc_msgSend
+// CHECK-X86_64: call double @objc_msgSend
+// CHECK-X86_64: call x86_fp80 @objc_msgSend_fpret
 // CHECK-X86_64: }
 //
 // CHECK-ARMV7-LABEL: define{{.*}} void @t0()
-// CHECK-ARMV7: call float bitcast {{.*}} @objc_msgSend to
-// CHECK-ARMV7: call double bitcast {{.*}} @objc_msgSend to
-// CHECK-ARMV7: call double bitcast {{.*}} @objc_msgSend to
+// CHECK-ARMV7: call float @objc_msgSend
+// CHECK-ARMV7: call double @objc_msgSend
+// CHECK-ARMV7: call double @objc_msgSend
 // CHECK-ARMV7: }
 void t0(void) {
   [(A*)0 floatValue];

diff  --git a/clang/test/CodeGenObjC/fragile-arc.m b/clang/test/CodeGenObjC/fragile-arc.m
index 2313ed5d1ad64..7afa08bcf685b 100644
--- a/clang/test/CodeGenObjC/fragile-arc.m
+++ b/clang/test/CodeGenObjC/fragile-arc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS
 
 @class Opaque;
 
@@ -28,73 +28,49 @@ @interface A : Root {
 
 @implementation A
 // CHECK-LABEL: define internal void @"\01-[A testStrong]"
-// CHECK:      [[SELFVAR:%.*]] = alloca [[A:%.*]]*, align 4
+// CHECK:      [[SELFVAR:%.*]] = alloca ptr, align 4
 - (void) testStrong {
-// CHECK:      [[X:%.*]] = alloca [[OPAQUE:%.*]]*, align 4
-// CHECK:      [[SELF:%.*]] = load [[A]]*, [[A]]** [[SELFVAR]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 4
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = load [[OPAQUE]]*, [[OPAQUE]]** [[IVAR]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[OPAQUE]]*
-// CHECK-NEXT: store [[OPAQUE]]* [[T3]], [[OPAQUE]]** [[X]]
+// CHECK:      [[X:%x]] = alloca ptr, align 4
+// CHECK:      [[SELF:%.*]] = load ptr, ptr [[SELFVAR]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 4
+// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T1]]
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[X]]
   Opaque *x = strong;
-// CHECK-NEXT: [[VALUE:%.*]] = load [[OPAQUE]]*, [[OPAQUE]]** [[X]]
-// CHECK-NEXT: [[SELF:%.*]] = load [[A]]*, [[A]]** [[SELFVAR]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 4
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8**
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[VALUE]] to i8*
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* [[T1]])
+// CHECK-NEXT: [[VALUE:%.*]] = load ptr, ptr [[X]]
+// CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFVAR]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 4
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr [[VALUE]])
   strong = x;
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[X]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
 // CHECK-NEXT: ret void
 }
 
 // CHECK-LABEL: define internal void @"\01-[A testWeak]"
-// CHECK:      [[SELFVAR:%.*]] = alloca [[A]]*, align 4
+// CHECK:      [[SELFVAR:%.*]] = alloca ptr, align 4
 - (void) testWeak {
-// CHECK:      [[X:%.*]] = alloca [[OPAQUE]]*, align 4
-// CHECK:      [[SELF:%.*]] = load [[A]]*, [[A]]** [[SELFVAR]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 8
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8**
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T0]])
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]*
-// CHECK-NEXT: store [[OPAQUE]]* [[T2]], [[OPAQUE]]** [[X]]
+// CHECK:      [[X:%x]] = alloca ptr, align 4
+// CHECK:      [[SELF:%.*]] = load ptr, ptr [[SELFVAR]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 8
+// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T1]])
+// CHECK-NEXT: store ptr [[T2]], ptr [[X]]
   Opaque *x = weak;
-// CHECK-NEXT: [[VALUE:%.*]] = load [[OPAQUE]]*, [[OPAQUE]]** [[X]]
-// CHECK-NEXT: [[SELF:%.*]] = load [[A]]*, [[A]]** [[SELFVAR]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 8
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8**
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[OPAQUE]]* [[VALUE]] to i8*
-// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[T0]], i8* [[T1]])
+// CHECK-NEXT: [[VALUE:%.*]] = load ptr, ptr [[X]]
+// CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFVAR]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 8
+// CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[T1]], ptr [[VALUE]])
   weak = x;
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[X]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
 // CHECK-NEXT: ret void
 }
 
 // CHECK-LABEL: define internal void @"\01-[A .cxx_destruct]"
-// CHECK:      [[SELFVAR:%.*]] = alloca [[A]]*, align 4
-// CHECK:      [[SELF:%.*]] = load [[A]]*, [[A]]** [[SELFVAR]]
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 8
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8**
-// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[SELF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 4
-// CHECK-NEXT: [[IVAR:%.*]] = bitcast i8* [[T1]] to [[OPAQUE]]**
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[OPAQUE]]** [[IVAR]] to i8**
-// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
+// CHECK:      [[SELFVAR:%.*]] = alloca ptr, align 4
+// CHECK:      [[SELF:%.*]] = load ptr, ptr [[SELFVAR]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 8
+// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[T1]])
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i32 4
+// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null)
 // CHECK-NEXT: ret void
 @end
 
@@ -138,30 +114,26 @@ void testBlockLayoutWeak(__weak id x) {
 }
 
 // CHECK-LABEL: define{{.*}} void @testCatch()
-// CHECK: [[X:%.*]] = alloca [[A:%.*]]*, align 4
-// CHECK: [[Y:%.*]] = alloca i8*, align 4
+// CHECK: [[X:%.*]] = alloca ptr, align 4
+// CHECK: [[Y:%.*]] = alloca ptr, align 4
 // CHECK: call void @objc_exception_try_enter
 // CHECK: br i1
 // CHECK: call void @checkpoint(i32 noundef 0)
 // CHECK: call void @objc_exception_try_exit
 // CHECK: br label
 // CHECK: call void @checkpoint(i32 noundef 3)
-// CHECK: [[EXN:%.*]] = call i8* @objc_exception_extract
+// CHECK: [[EXN:%.*]] = call ptr @objc_exception_extract
 // CHECK: call i32 @objc_exception_match(
 // CHECK: br i1
-// CHECK: [[T0:%.*]] = bitcast i8* [[EXN]] to [[A]]*
-// CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]])
-// CHECK: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
-// CHECK: store [[A]]* [[T3]], [[A]]** [[X]]
+// CHECK: [[T2:%.*]] = call ptr @llvm.objc.retain(ptr [[EXN]])
+// CHECK: store ptr [[T2]], ptr [[X]]
 // CHECK: call void @checkpoint(i32 noundef 1)
-// CHECK: [[T0:%.*]] = bitcast [[A]]** [[X]] to i8**
-// CHECK: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null)
+// CHECK: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
 // CHECK: br label
-// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[EXN]])
-// CHECK: store i8* [[T0]], i8** [[Y]]
+// CHECK: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr [[EXN]])
+// CHECK: store ptr [[T0]], ptr [[Y]]
 // CHECK: call void @checkpoint(i32 noundef 2)
-// CHECK: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null)
+// CHECK: call void @llvm.objc.storeStrong(ptr [[Y]], ptr null)
 extern void checkpoint(int n);
 void testCatch(void) {
   @try {

diff  --git a/clang/test/CodeGenObjC/mangle-blocks.m b/clang/test/CodeGenObjC/mangle-blocks.m
index 2cdaa0386d95a..771030fdd2cf3 100644
--- a/clang/test/CodeGenObjC/mangle-blocks.m
+++ b/clang/test/CodeGenObjC/mangle-blocks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-ios -fblocks -emit-llvm -o - %s -Wno-objc-root-class \
+// RUN: %clang_cc1 -triple i386-apple-ios -fblocks -emit-llvm -o - %s -Wno-objc-root-class \
 // RUN:   | FileCheck %s
 
 void __assert_rtn(const char *, const char *, int, const char *);
@@ -21,8 +21,8 @@ @implementation Test
 // CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
 // CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
 
-// CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* noundef %.block_descriptor)
+// CHECK: define internal void @"__14-[Test mangle]_block_invoke"(ptr noundef %.block_descriptor)
 
-// CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* noundef %.block_descriptor){{.*}}{
-// CHECK: call void @__assert_rtn(i8* noundef getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* noundef getelementptr inbounds {{.*}}, i32 noundef 14, i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
+// CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(ptr noundef %.block_descriptor){{.*}}{
+// CHECK: call void @__assert_rtn(ptr noundef @"__func__.__14-[Test mangle]_block_invoke_2", ptr noundef {{.*}}, i32 noundef 14, ptr noundef @.str[[STR1]])
 // CHECK: }

diff  --git a/clang/test/CodeGenObjC/messages-2.m b/clang/test/CodeGenObjC/messages-2.m
index e9121d80933f1..311fbae757be0 100644
--- a/clang/test/CodeGenObjC/messages-2.m
+++ b/clang/test/CodeGenObjC/messages-2.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NF
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NF
 
 // Most of this test is apparently just verifying that we don't crash.
 
@@ -145,31 +145,27 @@ -(const float) returnAConstFloat {
 @end
 
 // rdar://problem/7854674
-// CHECK:    define{{.*}} void @test0([[A:%.*]]*
-// CHECK-NF: define{{.*}} void @test0([[A:%.*]]*
+// CHECK:    define{{.*}} void @test0(ptr
+// CHECK-NF: define{{.*}} void @test0(ptr
 void test0(A *x) {
-  // CHECK:         [[X:%.*]] = alloca [[A]]*
+  // CHECK:         [[X:%.*]] = alloca ptr
   // CHECK-NEXT:    [[POINT:%.*]] = alloca [[POINT_T:%.*]],
-  // CHECK:         [[T0:%.*]] = load [[A]]*, [[A]]** [[X]]
-  // CHECK:         [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-  // CHECK-NEXT:    icmp eq i8* [[T1]], null
+  // CHECK:         [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK:    icmp eq ptr [[T0]], null
   // CHECK-NEXT:    br i1
-  // CHECK:         call {{.*}} @objc_msgSend_stret to
+  // CHECK:         call {{.*}} @objc_msgSend_stret
   // CHECK-NEXT:    br label
-  // CHECK:         [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8*
-  // CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false)
+  // CHECK:    call void @llvm.memset.p0.i64(ptr align 4 [[POINT]], i8 0, i64 48, i1 false)
   // CHECK-NEXT:    br label
 
-  // CHECK-NF:      [[X:%.*]] = alloca [[A]]*
+  // CHECK-NF:      [[X:%.*]] = alloca ptr
   // CHECK-NF-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]],
-  // CHECK-NF:      [[T0:%.*]] = load [[A]]*, [[A]]** [[X]]
-  // CHECK-NF:      [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-  // CHECK-NF-NEXT: icmp eq i8* [[T1]], null
+  // CHECK-NF:      [[T0:%.*]] = load ptr, ptr [[X]]
+  // CHECK-NF: icmp eq ptr [[T0]], null
   // CHECK-NF-NEXT: br i1
-  // CHECK-NF:      call {{.*}} @objc_msgSend_stret to
+  // CHECK-NF:      call {{.*}} @objc_msgSend_stret
   // CHECK-NF-NEXT: br label
-  // CHECK-NF:      [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8*
-  // CHECK-NF-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false)
+  // CHECK-NF: call void @llvm.memset.p0.i64(ptr align 4 [[POINT]], i8 0, i64 48, i1 false)
   // CHECK-NF-NEXT: br label
   MyPoint point = [x returnAPoint];
 }

diff  --git a/clang/test/CodeGenObjC/messages.m b/clang/test/CodeGenObjC/messages.m
index 660f73d41dcb9..f93d35a8d60c1 100644
--- a/clang/test/CodeGenObjC/messages.m
+++ b/clang/test/CodeGenObjC/messages.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC-NF
-// RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=gcc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-GNU
-// RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=gnustep -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-GNU-NF
+// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC-NF
+// RUN: %clang_cc1 -fobjc-runtime=gcc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-GNU
+// RUN: %clang_cc1 -fobjc-runtime=gnustep -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-GNU-NF
 
 typedef struct {
   int x;
@@ -13,34 +13,34 @@ void f0(id a) {
   int i;
   MyPoint pt = { 1, 2};
 
-  // CHECK-MAC: call {{.*}} @objc_msgSend to
-  // CHECK-MAC-NF: call {{.*}} @objc_msgSend to
+  // CHECK-MAC: call {{.*}} @objc_msgSend
+  // CHECK-MAC-NF: call {{.*}} @objc_msgSend
   // CHECK-GNU: call {{.*}} @objc_msg_lookup(
   // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender(
   [a print0];
 
-  // CHECK-MAC: call {{.*}} @objc_msgSend to
-  // CHECK-MAC-NF: call {{.*}} @objc_msgSend to
+  // CHECK-MAC: call {{.*}} @objc_msgSend
+  // CHECK-MAC-NF: call {{.*}} @objc_msgSend
   // CHECK-GNU: call {{.*}} @objc_msg_lookup(
   // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender(
   [a print1: 10];
 
-  // CHECK-MAC: call {{.*}} @objc_msgSend to
-  // CHECK-MAC-NF: call {{.*}} @objc_msgSend to
+  // CHECK-MAC: call {{.*}} @objc_msgSend
+  // CHECK-MAC-NF: call {{.*}} @objc_msgSend
   // CHECK-GNU: call {{.*}} @objc_msg_lookup(
   // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender(
   [a print2: 10 and: "hello" and: 2.2];
 
-  // CHECK-MAC: call {{.*}} @objc_msgSend to
-  // CHECK-MAC-NF: call {{.*}} @objc_msgSend to
+  // CHECK-MAC: call {{.*}} @objc_msgSend
+  // CHECK-MAC-NF: call {{.*}} @objc_msgSend
   // CHECK-GNU: call {{.*}} @objc_msg_lookup(
   // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender(
   [a takeStruct: pt ];
   
   void *s = @selector(print0);
   for (i=0; i<2; ++i)
-    // CHECK-MAC: call {{.*}} @objc_msgSend to
-    // CHECK-MAC-NF: call {{.*}} @objc_msgSend to
+    // CHECK-MAC: call {{.*}} @objc_msgSend
+    // CHECK-MAC-NF: call {{.*}} @objc_msgSend
     // CHECK-GNU: call {{.*}} @objc_msg_lookup(
     // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender(
     [a performSelector:s];

diff  --git a/clang/test/CodeGenObjC/metadata-class-properties.m b/clang/test/CodeGenObjC/metadata-class-properties.m
index 11d5a78b9fcef..e7bb9d3b30dfb 100644
--- a/clang/test/CodeGenObjC/metadata-class-properties.m
+++ b/clang/test/CodeGenObjC/metadata-class-properties.m
@@ -1,34 +1,34 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.11  -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.10  -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NULL %s
-// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.11  -emit-llvm -o - -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck -check-prefix=CHECK-FRAGILE %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11  -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10  -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NULL %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11  -emit-llvm -o - -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck -check-prefix=CHECK-FRAGILE %s
 
 // CHECK: @"_OBJC_$_CLASS_PROP_LIST_Proto" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} i32 96, i32 {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Proto" {{.*}} }
+// CHECK: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} i32 96, i32 {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Proto" }
 // CHECK: @"_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"_OBJC_$_CATEGORY_Foo_$_Category" = internal global %struct._category_t { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" {{.*}}, i32 64 }, section "__DATA, __objc_const", align 8
+// CHECK: @"_OBJC_$_CATEGORY_Foo_$_Category" = internal global %struct._category_t { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Foo_$_Category", i32 64 }, section "__DATA, __objc_const", align 8
 
 // CHECK: @"_OBJC_$_CLASS_PROP_LIST_C" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_C" {{.*}} }, section "__DATA, __objc_const", align 8
+// CHECK: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_C" }, section "__DATA, __objc_const", align 8
 
 // CHECK: !{i32 1, !"Objective-C Class Properties", i32 64}
 
 // CHECK-NULL-NOT: @"_OBJC_$_CLASS_PROP_LIST_Proto"
-// CHECK-NULL: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} %struct._prop_list_t* null, i32 96, i32 {{.*}} %struct._prop_list_t* null }
+// CHECK-NULL: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} ptr null, i32 96, i32 {{.*}} ptr null }
 // CHECK-NULL-NOT: @"_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK-NULL: @"_OBJC_$_CATEGORY_Foo_$_Category" = internal global %struct._category_t { {{.*}} %struct._prop_list_t* null, %struct._prop_list_t* null, {{.*}} }, section "__DATA, __objc_const", align 8
+// CHECK-NULL: @"_OBJC_$_CATEGORY_Foo_$_Category" = internal global %struct._category_t { {{.*}} ptr null, ptr null, {{.*}} }, section "__DATA, __objc_const", align 8
 
 // CHECK-NULL-NOT: @"_OBJC_$_CLASS_PROP_LIST_C" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK-NULL: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { {{.*}} %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8
+// CHECK-NULL: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { {{.*}} ptr null }, section "__DATA, __objc_const", align 8
 
 // CHECK-NULL: !{i32 1, !"Objective-C Class Properties", i32 64}
 
 // CHECK-FRAGILE: @"OBJC_$_CLASS_PROP_PROTO_LIST_Proto" = private global {{.*}} section "__OBJC,__property,regular,no_dead_strip", align 8
-// CHECK-FRAGILE: @_OBJC_PROTOCOLEXT_Proto = internal global %struct._objc_protocol_extension { i32 48, {{.*}} @"OBJC_$_CLASS_PROP_PROTO_LIST_Proto" {{.*}} }, align 8
+// CHECK-FRAGILE: @_OBJC_PROTOCOLEXT_Proto = internal global %struct._objc_protocol_extension { i32 48, {{.*}} @"OBJC_$_CLASS_PROP_PROTO_LIST_Proto" }, align 8
 // CHECK-FRAGILE: @"_OBJC_$_CLASS_PROP_LIST_Foo_Category" = private global {{.*}} section "__OBJC,__property,regular,no_dead_strip", align 8
-// CHECK-FRAGILE: @OBJC_CATEGORY_Foo_Category = private global %struct._objc_category { {{.*}}, i32 64, {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Foo_Category" {{.*}} }, section "__OBJC,__category,regular,no_dead_strip", align 8
+// CHECK-FRAGILE: @OBJC_CATEGORY_Foo_Category = private global %struct._objc_category { {{.*}}, i32 64, {{.*}} @"_OBJC_$_CLASS_PROP_LIST_Foo_Category" }, section "__OBJC,__category,regular,no_dead_strip", align 8
 
 // CHECK-FRAGILE: @"_OBJC_$_CLASS_PROP_LIST_C" = private global {{.*}} section "__OBJC,__property,regular,no_dead_strip", align 8
-// CHECK-FRAGILE: @OBJC_CLASSEXT_C = private global %struct._objc_class_extension { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_C" {{.*}} }, section "__OBJC,__class_ext,regular,no_dead_strip", align 8
+// CHECK-FRAGILE: @OBJC_CLASSEXT_C = private global %struct._objc_class_extension { {{.*}} @"_OBJC_$_CLASS_PROP_LIST_C" }, section "__OBJC,__class_ext,regular,no_dead_strip", align 8
 
 // CHECK-FRAGILE: !{i32 1, !"Objective-C Class Properties", i32 64}
 


        


More information about the cfe-commits mailing list