[clang] b6dab4e - Pass -disable-llvm-passes to avoid running llvm passes

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 28 11:15:53 PDT 2022


Author: Akira Hatanaka
Date: 2022-03-28T11:14:44-07:00
New Revision: b6dab4ebac595c61ed00c8559307a15fd3b9d077

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

LOG: Pass -disable-llvm-passes to avoid running llvm passes

Differential Revision: https://reviews.llvm.org/D122425

Added: 
    

Modified: 
    clang/test/CodeGenCXX/nrvo.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp
index 542d6d98b0a6c..c1f5196e8d8cb 100644
--- a/clang/test/CodeGenCXX/nrvo.cpp
+++ b/clang/test/CodeGenCXX/nrvo.cpp
@@ -1,7 +1,7 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -DCXX11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH-03 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++11 -DCXX11 -o - %s | FileCheck --check-prefixes=CHECK-EH-11 %s
 
 // Test code generation for the named return value optimization.
 class X {
@@ -25,13 +25,54 @@ extern X OuterX;
 
 // CHECK-LABEL: @_Z5test0v(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4:[0-9]+]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
 // CHECK-NEXT:    ret void
 //
-// CHECK-EH-LABEL: @_Z5test0v(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z5test0v(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z5test0v(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7:[0-9]+]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    ret void
 //
 X test0() { // http://wg21.link/p2025r2#ex-2
   X x;
@@ -40,13 +81,99 @@ X test0() { // http://wg21.link/p2025r2#ex-2
 
 // CHECK-LABEL: @_Z5test1b(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3:![0-9]+]]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7:![0-9]+]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       cleanup:
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
 // CHECK-NEXT:    ret void
 //
-// CHECK-EH-LABEL: @_Z5test1b(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z5test1b(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3:![0-9]+]]
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7:![0-9]+]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       cleanup:
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z5test1b(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3:![0-9]+]]
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7:![0-9]+]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       cleanup:
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    ret void
 //
 X test1(bool B) {
   X x;
@@ -57,105 +184,202 @@ X test1(bool B) {
 
 // CHECK-LABEL: @_Z5test2b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    [[Y_X:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y_X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       cleanup:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP4:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP4]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z5test2b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6:[0-9]+]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
+// CHECK-EH-03:       invoke.cont2:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-03:       lpad1:
-// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]]
+// CHECK-EH-03:       invoke.cont3:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-03:       cleanup:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]]
 // CHECK-EH-03:       invoke.cont4:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP10]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP11]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       invoke.cont5:
+// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-03:       ehcleanup:
-// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD]] ], [ [[TMP4]], [[LPAD1]] ]
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP12]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT9:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont9:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[DOTPN]]
+// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP13]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL12:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL12]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP14:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8:[0-9]+]]
+// CHECK-EH-03-NEXT:    [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR7:[0-9]+]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z5test2b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
+// CHECK-EH-11:       invoke.cont2:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-11:       lpad1:
-// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]]
+// CHECK-EH-11:       invoke.cont3:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       cleanup:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP10]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP11]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       ehcleanup:
-// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD1]] ], [ [[TMP3]], [[LPAD]] ]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP12]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN]]
+// CHECK-EH-11-NEXT:    [[TMP13:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP13]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL9:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL9]]
 //
 X test2(bool B) {
   X x;
@@ -167,81 +391,161 @@ X test2(bool B) {
 
 // CHECK-LABEL: @_Z5test3b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
 // CHECK-NEXT:    br label [[RETURN:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z5test3b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
 // CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-03:       if.end:
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL2]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z5test3b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
 // CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-11:       if.end:
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test3(bool B) { // http://wg21.link/p2025r2#ex-4
   if (B) {
@@ -256,36 +560,129 @@ extern "C" void exit(int) throw();
 
 // CHECK-LABEL: @_Z5test4b(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       cleanup:
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK:       nrvo.unused:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
+// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-NEXT:    ]
+// CHECK:       cleanup.cont:
+// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR4]]
 // CHECK-NEXT:    unreachable
 // CHECK:       return:
 // CHECK-NEXT:    ret void
+// CHECK:       unreachable:
+// CHECK-NEXT:    unreachable
 //
 // CHECK-EH-03-LABEL: @_Z5test4b(
 // CHECK-EH-03-NEXT:  entry:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       cleanup:
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-03:       nrvo.unused:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
-// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-03-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-03-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-03-NEXT:    ]
+// CHECK-EH-03:       cleanup.cont:
+// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    unreachable
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       unreachable:
+// CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z5test4b(
 // CHECK-EH-11-NEXT:  entry:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       cleanup:
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-11:       nrvo.unused:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-11-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-11-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-11-NEXT:    ]
+// CHECK-EH-11:       cleanup.cont:
 // CHECK-EH-11-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    unreachable
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       unreachable:
+// CHECK-EH-11-NEXT:    unreachable
 //
 X test4(bool B) {
   {
@@ -300,111 +697,160 @@ X test4(bool B) {
 void may_throw();
 // CHECK-EH-03-LABEL: @_Z5test5v(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_Z9may_throwv()
-// CHECK-EH-03-NEXT:    to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    br label [[TRY_CONT:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP2]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CATCH_DISPATCH:%.*]]
+// CHECK-EH-03:       catch.dispatch:
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]]
 // CHECK-EH-03-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       catch:
-// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X*
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]])
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %class.X*
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP7]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]
 // CHECK-EH-03:       invoke.cont3:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]]
 // CHECK-EH-03:       lpad2:
-// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP10]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    to label [[EHCLEANUP:%.*]] unwind label [[TERMINATE_LPAD]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont5:
 // CHECK-EH-03-NEXT:    call void @__cxa_end_catch()
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP12]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       lpad4:
-// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP14]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]
+// CHECK-EH-03:       invoke.cont6:
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-03:       ehcleanup:
-// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP9]], [[LPAD4]] ], [ [[TMP8]], [[LPAD2]] ]
 // CHECK-EH-03-NEXT:    invoke void @__cxa_end_catch()
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont7:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP16:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP16]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[EH_RESUME]]
 // CHECK-EH-03:       try.cont:
 // CHECK-EH-03-NEXT:    unreachable
 // CHECK-EH-03:       eh.resume:
-// CHECK-EH-03-NEXT:    [[LPAD_VAL11_MERGED:%.*]] = phi { i8*, i32 } [ [[DOTPN]], [[INVOKE_CONT7]] ], [ [[TMP0]], [[LPAD]] ]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL11_MERGED]]
+// CHECK-EH-03-NEXT:    [[EXN9:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL10:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN9]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL10]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL11]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP17:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP11]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z5test5v(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
 // CHECK-EH-11-NEXT:    invoke void @_Z9may_throwv()
-// CHECK-EH-11-NEXT:    to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    br label [[TRY_CONT:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP2]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CATCH_DISPATCH:%.*]]
+// CHECK-EH-11:       catch.dispatch:
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]]
 // CHECK-EH-11-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       catch:
-// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X*
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]])
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %class.X*
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP7]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont1:
-// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]
 // CHECK-EH-11:       invoke.cont3:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @__cxa_end_catch()
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       lpad2:
-// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP11]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP12]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    invoke void @__cxa_end_catch()
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-11:       invoke.cont4:
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP13:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP13]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EH_RESUME]]
 // CHECK-EH-11:       try.cont:
 // CHECK-EH-11-NEXT:    unreachable
 // CHECK-EH-11:       eh.resume:
-// CHECK-EH-11-NEXT:    [[LPAD_VAL7_MERGED:%.*]] = phi { i8*, i32 } [ [[TMP8]], [[INVOKE_CONT4]] ], [ [[TMP0]], [[LPAD]] ]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL7_MERGED]]
+// CHECK-EH-11-NEXT:    [[EXN5:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL6:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN5]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL7:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL6]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL7]]
 // CHECK-EH-11:       terminate.lpad:
-// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP14:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    catch i8* null
-// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0
-// CHECK-EH-11-NEXT:    call void @__clang_call_terminate(i8* [[TMP10]]) #[[ATTR8:[0-9]+]]
+// CHECK-EH-11-NEXT:    [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0
+// CHECK-EH-11-NEXT:    call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR8:[0-9]+]]
 // CHECK-EH-11-NEXT:    unreachable
 //
 X test5() { // http://wg21.link/p2025r2#ex-14
@@ -419,60 +865,98 @@ X test5() { // http://wg21.link/p2025r2#ex-14
 // rdar://problem/10430868
 // CHECK-LABEL: @_Z5test6v(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z5test6v(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-EH-03-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL2]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP8]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z5test6v(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-EH-11-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[A]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test6() {
   X a __attribute__((aligned(8)));
@@ -481,13 +965,90 @@ X test6() {
 
 // CHECK-LABEL: @_Z5test7b(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
+// CHECK-NEXT:    br label [[RETURN:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    br label [[RETURN]]
+// CHECK:       return:
 // CHECK-NEXT:    ret void
 //
-// CHECK-EH-LABEL: @_Z5test7b(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z5test7b(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[RETURN]]
+// CHECK-EH-03:       return:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z5test7b(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    br label [[RETURN]]
+// CHECK-EH-11:       return:
+// CHECK-EH-11-NEXT:    ret void
 //
 X test7(bool b) {
   if (b) {
@@ -499,13 +1060,117 @@ X test7(bool b) {
 
 // CHECK-LABEL: @_Z5test8b(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
+// CHECK-NEXT:    br label [[RETURN:%.*]]
+// CHECK:       if.else:
+// CHECK-NEXT:    store i1 false, i1* [[NRVO1]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO1]], align 1
+// CHECK-NEXT:    [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]
+// CHECK:       nrvo.unused3:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR4]]
+// CHECK:       nrvo.skipdtor4:
+// CHECK-NEXT:    br label [[RETURN]]
+// CHECK:       return:
 // CHECK-NEXT:    ret void
 //
-// CHECK-EH-LABEL: @_Z5test8b(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z5test8b(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-03:       if.else:
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO1]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO1]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]
+// CHECK-EH-03:       nrvo.unused3:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR4]]
+// CHECK-EH-03:       nrvo.skipdtor4:
+// CHECK-EH-03-NEXT:    br label [[RETURN]]
+// CHECK-EH-03:       return:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z5test8b(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-11:       if.else:
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO1]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO1]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]
+// CHECK-EH-11:       nrvo.unused3:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR4]]
+// CHECK-EH-11:       nrvo.skipdtor4:
+// CHECK-EH-11-NEXT:    br label [[RETURN]]
+// CHECK-EH-11:       return:
+// CHECK-EH-11-NEXT:    ret void
 //
 X test8(bool b) {
   if (b) {
@@ -519,19 +1184,42 @@ X test8(bool b) {
 
 // CHECK-LABEL: @_Z5test9v(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]])
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]])
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
 // CHECK-NEXT:    unreachable
 //
-// CHECK-EH-LABEL: @_Z5test9v(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
-// CHECK-EH-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0
-// CHECK-EH-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
-// CHECK-EH-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]])
-// CHECK-EH-NEXT:    unreachable
+// CHECK-EH-03-LABEL: @_Z5test9v(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]])
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    unreachable
+//
+// CHECK-EH-11-LABEL: @_Z5test9v(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]])
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %struct.Y* [[TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    unreachable
 //
 Y<int> test9() {
   Y<int>::f();
@@ -539,77 +1227,147 @@ Y<int> test9() {
 
 // CHECK-LABEL: @_Z6test10b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK:       if.else:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       cleanup:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test10b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       if.else:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP]] unwind label [[LPAD]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]
+// CHECK-EH-03:       invoke.cont1:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-03:       cleanup:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       invoke.cont2:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL4:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL4]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test10b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       if.else:
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP]] unwind label [[LPAD]]
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]
+// CHECK-EH-11:       invoke.cont1:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       cleanup:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL3]]
 //
 X test10(bool b) { // http://wg21.link/p2025r2#ex-3
   X x;
@@ -621,77 +1379,147 @@ X test10(bool b) { // http://wg21.link/p2025r2#ex-3
 
 // CHECK-LABEL: @_Z6test11b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       cleanup:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test11b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       if.end:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP]] unwind label [[LPAD]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]
+// CHECK-EH-03:       invoke.cont1:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-03:       cleanup:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       invoke.cont2:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL4:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL4]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test11b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       if.end:
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP]] unwind label [[LPAD]]
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]
+// CHECK-EH-11:       invoke.cont1:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       cleanup:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL3]]
 //
 X test11(bool b) { // http://wg21.link/p2025r2#ex-5
   X x;
@@ -702,36 +1530,135 @@ X test11(bool b) { // http://wg21.link/p2025r2#ex-5
 
 // CHECK-LABEL: @_Z6test12b(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    br label [[DO_BODY:%.*]]
+// CHECK:       do.body:
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       cleanup:
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK:       nrvo.unused:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
+// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-NEXT:    i32 2, label [[DO_END:%.*]]
+// CHECK-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-NEXT:    ]
+// CHECK:       do.end:
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
+// CHECK:       unreachable:
+// CHECK-NEXT:    unreachable
 //
 // CHECK-EH-03-LABEL: @_Z6test12b(
 // CHECK-EH-03-NEXT:  entry:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]]
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    br label [[DO_BODY:%.*]]
+// CHECK-EH-03:       do.body:
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       cleanup:
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-03:       nrvo.unused:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-03-NEXT:    i32 2, label [[DO_END:%.*]]
+// CHECK-EH-03-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-03-NEXT:    ]
+// CHECK-EH-03:       do.end:
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       unreachable:
+// CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test12b(
 // CHECK-EH-11-NEXT:  entry:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]]
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    br label [[DO_BODY:%.*]]
+// CHECK-EH-11:       do.body:
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       cleanup:
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-11:       nrvo.unused:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-11-NEXT:    i32 2, label [[DO_END:%.*]]
+// CHECK-EH-11-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-11-NEXT:    ]
+// CHECK-EH-11:       do.end:
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       unreachable:
+// CHECK-EH-11-NEXT:    unreachable
 //
 X test12(bool b) { // http://wg21.link/p2025r2#ex-6
   do {
@@ -745,81 +1672,134 @@ X test12(bool b) { // http://wg21.link/p2025r2#ex-6
 
 // CHECK-LABEL: @_Z6test13b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-NEXT:    br label [[RETURN:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test13b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-03:       if.end:
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL2]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test13b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-11:       if.end:
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test13(bool b) { // http://wg21.link/p2025r2#ex-7
   if (b)
@@ -830,137 +1810,222 @@ X test13(bool b) { // http://wg21.link/p2025r2#ex-7
 
 // CHECK-LABEL: @_Z6test14b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP4:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP4]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       cleanup:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test14b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP7:%.*]]
 // CHECK-EH-03:       if.end:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
 // CHECK-EH-03:       invoke.cont2:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]]
 // CHECK-EH-03:       invoke.cont4:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]]
 // CHECK-EH-03:       lpad1:
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-03:       lpad3:
-// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP11]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP12]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont5:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP13]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       invoke.cont6:
+// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-03:       ehcleanup:
-// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD1]] ], [ [[TMP4]], [[LPAD3]] ]
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP7]]
 // CHECK-EH-03:       cleanup:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP15:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP15]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       ehcleanup7:
-// CHECK-EH-03-NEXT:    [[DOTPN13:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont8:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[DOTPN13]]
+// CHECK-EH-03-NEXT:    [[TMP16:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP16]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL11]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP17:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test14b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP5:%.*]]
 // CHECK-EH-11:       if.end:
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
 // CHECK-EH-11:       invoke.cont2:
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]]
 // CHECK-EH-11:       invoke.cont4:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       lpad1:
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP9]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP10]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-11:       lpad3:
-// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-11:       ehcleanup:
-// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD3]] ], [ [[TMP3]], [[LPAD1]] ]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP5]]
 // CHECK-EH-11:       cleanup:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP15:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP15]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       ehcleanup5:
-// CHECK-EH-11-NEXT:    [[DOTPN10:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN10]]
+// CHECK-EH-11-NEXT:    [[TMP16:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP16]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL8:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL8]]
 //
 X test14(bool b) { // http://wg21.link/p2025r2#ex-8
   X x;
@@ -972,137 +2037,222 @@ X test14(bool b) { // http://wg21.link/p2025r2#ex-8
 
 // CHECK-LABEL: @_Z6test15b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP4:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP4]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       cleanup:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test15b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP7:%.*]]
 // CHECK-EH-03:       if.end:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
 // CHECK-EH-03:       invoke.cont2:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]]
 // CHECK-EH-03:       invoke.cont4:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]]
 // CHECK-EH-03:       lpad1:
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-03:       lpad3:
-// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP11]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP12]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont5:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP13]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       invoke.cont6:
+// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-03:       ehcleanup:
-// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD1]] ], [ [[TMP4]], [[LPAD3]] ]
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[EHCLEANUP7]]
 // CHECK-EH-03:       cleanup:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP15:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP15]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       ehcleanup7:
-// CHECK-EH-03-NEXT:    [[DOTPN13:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ]
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont8:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[DOTPN13]]
+// CHECK-EH-03-NEXT:    [[TMP16:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP16]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL11]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP17:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test15b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP5:%.*]]
 // CHECK-EH-11:       if.end:
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
 // CHECK-EH-11:       invoke.cont2:
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]]
 // CHECK-EH-11:       invoke.cont4:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       lpad1:
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP9]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP10]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-11:       lpad3:
-// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-11:       ehcleanup:
-// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD3]] ], [ [[TMP3]], [[LPAD1]] ]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP5]]
 // CHECK-EH-11:       cleanup:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP15:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP15]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       ehcleanup5:
-// CHECK-EH-11-NEXT:    [[DOTPN10:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN10]]
+// CHECK-EH-11-NEXT:    [[TMP16:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP16]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL8:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL8]]
 //
 X test15(bool b) { // http://wg21.link/p2025r2#ex-15
   X x;
@@ -1117,33 +2267,59 @@ X test15(bool b) { // http://wg21.link/p2025r2#ex-15
 // CHECK-EH-11-NEXT:  entry:
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-EH-11-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 4
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP0]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.anon* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 0
+// CHECK-EH-11-NEXT:    store %class.X* [[X]], %class.X** [[TMP2]], align 4, !tbaa [[TBAA8:![0-9]+]]
+// CHECK-EH-11-NEXT:    invoke void @"_ZZ6test16vENK3$_0clEv"(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP]], %class.anon* noundef nonnull align 4 dereferenceable(4) [[REF_TMP]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
-// CHECK-EH-11-NEXT:    invoke void @_Z8ConsumeX1X(%class.X* noundef nonnull [[AGG_TMP]])
+// CHECK-EH-11-NEXT:    invoke void @_Z8ConsumeX1X(%class.X* noundef [[AGG_TMP]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
 // CHECK-EH-11:       invoke.cont2:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = bitcast %class.anon* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP4]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP6]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP7]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]
 // CHECK-EH-11:       lpad1:
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP9]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP10]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]
 // CHECK-EH-11:       ehcleanup:
-// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP2]], [[LPAD1]] ], [ [[TMP1]], [[LPAD]] ]
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = bitcast %class.anon* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN]]
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP12]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL5:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL5]]
 //
 void test16() { // http://wg21.link/p2025r2#ex-9
   X x;
@@ -1156,50 +2332,95 @@ void test16() { // http://wg21.link/p2025r2#ex-9
 
 // CHECK-LABEL: @_Z6test17i(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3
-// CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA8:![0-9]+]]
+// CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    br label [[IMPOSSIBLE:%.*]]
 // CHECK:       impossible:
-// CHECK-NEXT:    br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]]
-// CHECK:       while.body.backedge:
-// CHECK-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
+// CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then1:
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    br label [[RETURN:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    br label [[IF_END2]]
+// CHECK:       if.end2:
+// CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
 // CHECK:       while.body:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
-// CHECK-NEXT:    switch i32 [[I]], label [[IF_END20:%.*]] [
-// CHECK-NEXT:    i32 0, label [[CLEANUP:%.*]]
-// CHECK-NEXT:    i32 1, label [[IF_THEN7:%.*]]
-// CHECK-NEXT:    i32 2, label [[IF_THEN10:%.*]]
-// CHECK-NEXT:    i32 3, label [[IF_THEN13:%.*]]
-// CHECK-NEXT:    i32 4, label [[IF_THEN16:%.*]]
-// CHECK-NEXT:    i32 5, label [[CLEANUP]]
-// CHECK-NEXT:    ]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+// CHECK-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
+// CHECK:       if.then4:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end5:
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]
 // CHECK:       if.then7:
+// CHECK-NEXT:    store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       if.end8:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2
+// CHECK-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]
 // CHECK:       if.then10:
-// CHECK-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP3]]
+// CHECK-NEXT:    store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP10:![0-9]+]]
+// CHECK:       if.end11:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3
+// CHECK-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]
 // CHECK:       if.then13:
+// CHECK-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       if.end14:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4
+// CHECK-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]
 // CHECK:       if.then16:
-// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR5]]
-// CHECK-NEXT:    br label [[IF_END20]]
+// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR4]]
+// CHECK-NEXT:    br label [[IF_END17]]
+// CHECK:       if.end17:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5
+// CHECK-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]
+// CHECK:       if.then19:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       if.end20:
+// CHECK-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-NEXT:    br label [[CLEANUP]]
 // CHECK:       cleanup:
-// CHECK-NEXT:    [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ]
-// CHECK-NEXT:    [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ]
-// CHECK-NEXT:    br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK:       nrvo.unused:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
 // CHECK:       nrvo.skipdtor:
-// CHECK-NEXT:    switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [
-// CHECK-NEXT:    i32 0, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-NEXT:    i32 1, label [[RETURN:%.*]]
-// CHECK-NEXT:    i32 4, label [[RETURN_SINK_SPLIT]]
-// CHECK-NEXT:    i32 3, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-NEXT:    i32 2, label [[IMPOSSIBLE:%.*]]
+// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-NEXT:    i32 1, label [[RETURN]]
+// CHECK-NEXT:    i32 4, label [[WHILE_END:%.*]]
+// CHECK-NEXT:    i32 3, label [[WHILE_BODY]]
+// CHECK-NEXT:    i32 2, label [[IMPOSSIBLE]]
 // CHECK-NEXT:    ]
-// CHECK:       return.sink.split:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
+// CHECK:       cleanup.cont:
+// CHECK-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP10]]
+// CHECK:       while.end:
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
@@ -1208,49 +2429,94 @@ void test16() { // http://wg21.link/p2025r2#ex-9
 //
 // CHECK-EH-03-LABEL: @_Z6test17i(
 // CHECK-EH-03-NEXT:  entry:
-// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3
-// CHECK-EH-03-NEXT:    br label [[WHILE_BODY:%.*]]
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA8:![0-9]+]]
+// CHECK-EH-03-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    br label [[IMPOSSIBLE:%.*]]
 // CHECK-EH-03:       impossible:
-// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]]
-// CHECK-EH-03:       while.body.backedge:
-// CHECK-EH-03-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
+// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then1:
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    br label [[IF_END2]]
+// CHECK-EH-03:       if.end2:
+// CHECK-EH-03-NEXT:    br label [[WHILE_BODY:%.*]]
 // CHECK-EH-03:       while.body:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-03-NEXT:    switch i32 [[I]], label [[IF_END20:%.*]] [
-// CHECK-EH-03-NEXT:    i32 0, label [[CLEANUP:%.*]]
-// CHECK-EH-03-NEXT:    i32 1, label [[IF_THEN7:%.*]]
-// CHECK-EH-03-NEXT:    i32 2, label [[IF_THEN10:%.*]]
-// CHECK-EH-03-NEXT:    i32 3, label [[IF_THEN13:%.*]]
-// CHECK-EH-03-NEXT:    i32 4, label [[IF_THEN16:%.*]]
-// CHECK-EH-03-NEXT:    i32 5, label [[CLEANUP]]
-// CHECK-EH-03-NEXT:    ]
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+// CHECK-EH-03-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
+// CHECK-EH-03:       if.then4:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-03:       if.end5:
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-EH-03-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]
 // CHECK-EH-03:       if.then7:
+// CHECK-EH-03-NEXT:    store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       if.end8:
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2
+// CHECK-EH-03-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]
 // CHECK-EH-03:       if.then10:
-// CHECK-EH-03-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP3]]
+// CHECK-EH-03-NEXT:    store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP10:![0-9]+]]
+// CHECK-EH-03:       if.end11:
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3
+// CHECK-EH-03-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]
 // CHECK-EH-03:       if.then13:
+// CHECK-EH-03-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       if.end14:
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4
+// CHECK-EH-03-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]
 // CHECK-EH-03:       if.then16:
-// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    br label [[IF_END20]]
+// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[IF_END17]]
+// CHECK-EH-03:       if.end17:
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5
+// CHECK-EH-03-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]
+// CHECK-EH-03:       if.then19:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-03:       if.end20:
+// CHECK-EH-03-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-03:       cleanup:
-// CHECK-EH-03-NEXT:    [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ]
-// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ]
-// CHECK-EH-03-NEXT:    br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-03:       nrvo.unused:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
 // CHECK-EH-03:       nrvo.skipdtor:
-// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [
-// CHECK-EH-03-NEXT:    i32 0, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-EH-03-NEXT:    i32 1, label [[RETURN:%.*]]
-// CHECK-EH-03-NEXT:    i32 4, label [[RETURN_SINK_SPLIT]]
-// CHECK-EH-03-NEXT:    i32 3, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-EH-03-NEXT:    i32 2, label [[IMPOSSIBLE:%.*]]
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-03-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-03-NEXT:    i32 1, label [[RETURN]]
+// CHECK-EH-03-NEXT:    i32 4, label [[WHILE_END:%.*]]
+// CHECK-EH-03-NEXT:    i32 3, label [[WHILE_BODY]]
+// CHECK-EH-03-NEXT:    i32 2, label [[IMPOSSIBLE]]
 // CHECK-EH-03-NEXT:    ]
-// CHECK-EH-03:       return.sink.split:
+// CHECK-EH-03:       cleanup.cont:
+// CHECK-EH-03-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP10]]
+// CHECK-EH-03:       while.end:
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       return:
@@ -1260,49 +2526,94 @@ void test16() { // http://wg21.link/p2025r2#ex-9
 //
 // CHECK-EH-11-LABEL: @_Z6test17i(
 // CHECK-EH-11-NEXT:  entry:
-// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3
-// CHECK-EH-11-NEXT:    br label [[WHILE_BODY:%.*]]
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA12:![0-9]+]]
+// CHECK-EH-11-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    br label [[IMPOSSIBLE:%.*]]
 // CHECK-EH-11:       impossible:
-// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]]
-// CHECK-EH-11:       while.body.backedge:
-// CHECK-EH-11-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
+// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then1:
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    br label [[IF_END2]]
+// CHECK-EH-11:       if.end2:
+// CHECK-EH-11-NEXT:    br label [[WHILE_BODY:%.*]]
 // CHECK-EH-11:       while.body:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    switch i32 [[I]], label [[IF_END20:%.*]] [
-// CHECK-EH-11-NEXT:    i32 0, label [[CLEANUP:%.*]]
-// CHECK-EH-11-NEXT:    i32 1, label [[IF_THEN7:%.*]]
-// CHECK-EH-11-NEXT:    i32 2, label [[IF_THEN10:%.*]]
-// CHECK-EH-11-NEXT:    i32 3, label [[IF_THEN13:%.*]]
-// CHECK-EH-11-NEXT:    i32 4, label [[IF_THEN16:%.*]]
-// CHECK-EH-11-NEXT:    i32 5, label [[CLEANUP]]
-// CHECK-EH-11-NEXT:    ]
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+// CHECK-EH-11-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
+// CHECK-EH-11:       if.then4:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-11:       if.end5:
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-EH-11-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]
 // CHECK-EH-11:       if.then7:
+// CHECK-EH-11-NEXT:    store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       if.end8:
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2
+// CHECK-EH-11-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]
 // CHECK-EH-11:       if.then10:
-// CHECK-EH-11-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP3]]
+// CHECK-EH-11-NEXT:    store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP14:![0-9]+]]
+// CHECK-EH-11:       if.end11:
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3
+// CHECK-EH-11-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]
 // CHECK-EH-11:       if.then13:
+// CHECK-EH-11-NEXT:    store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       if.end14:
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4
+// CHECK-EH-11-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]
 // CHECK-EH-11:       if.then16:
 // CHECK-EH-11-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    br label [[IF_END20]]
+// CHECK-EH-11-NEXT:    br label [[IF_END17]]
+// CHECK-EH-11:       if.end17:
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5
+// CHECK-EH-11-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]
+// CHECK-EH-11:       if.then19:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       if.end20:
+// CHECK-EH-11-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    br label [[CLEANUP]]
 // CHECK-EH-11:       cleanup:
-// CHECK-EH-11-NEXT:    [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ]
-// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ]
-// CHECK-EH-11-NEXT:    br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-11:       nrvo.unused:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
 // CHECK-EH-11:       nrvo.skipdtor:
-// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [
-// CHECK-EH-11-NEXT:    i32 0, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-EH-11-NEXT:    i32 1, label [[RETURN:%.*]]
-// CHECK-EH-11-NEXT:    i32 4, label [[RETURN_SINK_SPLIT]]
-// CHECK-EH-11-NEXT:    i32 3, label [[WHILE_BODY_BACKEDGE]]
-// CHECK-EH-11-NEXT:    i32 2, label [[IMPOSSIBLE:%.*]]
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-11-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-11-NEXT:    i32 1, label [[RETURN]]
+// CHECK-EH-11-NEXT:    i32 4, label [[WHILE_END:%.*]]
+// CHECK-EH-11-NEXT:    i32 3, label [[WHILE_BODY]]
+// CHECK-EH-11-NEXT:    i32 2, label [[IMPOSSIBLE]]
 // CHECK-EH-11-NEXT:    ]
-// CHECK-EH-11:       return.sink.split:
+// CHECK-EH-11:       cleanup.cont:
+// CHECK-EH-11-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP14]]
+// CHECK-EH-11:       while.end:
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       return:
@@ -1337,151 +2648,300 @@ X test17(int i) { // http://wg21.link/p2025r2#ex-10
 
 // CHECK-LABEL: @_Z6test18i(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-NEXT:    [[Z:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
-// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0
-// CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+// CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK:       if.then:
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK:       if.end:
+// CHECK-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP]]
+// CHECK:       cleanup:
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK:       nrvo.unused:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I]], 1
-// CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT7_CRITEDGE:%.*]]
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
+// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-NEXT:    ]
+// CHECK:       cleanup.cont:
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
 // CHECK:       if.then2:
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    br label [[RETURN]]
-// CHECK:       cleanup.cont7.critedge:
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP4:%.*]]
+// CHECK:       if.end3:
+// CHECK-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    br label [[CLEANUP4]]
+// CHECK:       cleanup4:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP4:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP4]]) #[[ATTR4]]
+// CHECK-NEXT:    [[CLEANUP_DEST6:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    switch i32 [[CLEANUP_DEST6]], label [[UNREACHABLE]] [
+// CHECK-NEXT:    i32 0, label [[CLEANUP_CONT7:%.*]]
+// CHECK-NEXT:    i32 1, label [[RETURN]]
+// CHECK-NEXT:    ]
+// CHECK:       cleanup.cont7:
+// CHECK-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
+// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
+// CHECK-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
+// CHECK:       unreachable:
+// CHECK-NEXT:    unreachable
 //
 // CHECK-EH-03-LABEL: @_Z6test18i(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-03-NEXT:    [[Z:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0
-// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03:       if.then:
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-03:       if.end:
+// CHECK-EH-03-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-03:       cleanup:
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-03:       nrvo.unused:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-03-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-03-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-03-NEXT:    ]
+// CHECK-EH-03:       cleanup.cont:
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I]], 1
-// CHECK-EH-03-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT8_CRITEDGE:%.*]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-03-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-EH-03-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
 // CHECK-EH-03:       if.then2:
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    to label [[CLEANUP4:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-03:       invoke.cont:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP4:%.*]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
+// CHECK-EH-03:       if.end3:
+// CHECK-EH-03-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    br label [[CLEANUP4]]
 // CHECK-EH-03:       cleanup4:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    br i1 [[CMP1]], label [[RETURN]], label [[CLEANUP_CONT8:%.*]]
-// CHECK-EH-03:       cleanup.cont8.critedge:
-// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    br label [[CLEANUP_CONT8]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    [[CLEANUP_DEST7:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST7]], label [[UNREACHABLE]] [
+// CHECK-EH-03-NEXT:    i32 0, label [[CLEANUP_CONT8:%.*]]
+// CHECK-EH-03-NEXT:    i32 1, label [[RETURN]]
+// CHECK-EH-03-NEXT:    ]
 // CHECK-EH-03:       cleanup.cont8:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP8]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT10:%.*]] unwind label [[LPAD9:%.*]]
 // CHECK-EH-03:       invoke.cont10:
+// CHECK-EH-03-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP9]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       invoke.cont5:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP10]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       lpad9:
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT12:%.*]] unwind label [[TERMINATE_LPAD]]
 // CHECK-EH-03:       invoke.cont12:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[EH_RESUME]]
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       eh.resume:
-// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[INVOKE_CONT12]] ], [ [[TMP1]], [[INVOKE_CONT5]] ]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[DOTPN]]
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL14:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL14]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP15:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP15]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP16]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    unreachable
+// CHECK-EH-03:       unreachable:
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test18i(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
 // CHECK-EH-11-NEXT:    [[Z:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0
-// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i32 [[I:%.*]], i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11:       if.then:
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]
+// CHECK-EH-11:       if.end:
+// CHECK-EH-11-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP]]
+// CHECK-EH-11:       cleanup:
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-11:       nrvo.unused:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [
+// CHECK-EH-11-NEXT:    i32 0, label [[CLEANUP_CONT:%.*]]
+// CHECK-EH-11-NEXT:    i32 1, label [[RETURN:%.*]]
+// CHECK-EH-11-NEXT:    ]
+// CHECK-EH-11:       cleanup.cont:
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-11-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I]], 1
-// CHECK-EH-11-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT7_CRITEDGE:%.*]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4, !tbaa [[TBAA12]]
+// CHECK-EH-11-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1
+// CHECK-EH-11-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
 // CHECK-EH-11:       if.then2:
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-11-NEXT:    to label [[CLEANUP4:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP4:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       if.end3:
+// CHECK-EH-11-NEXT:    store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    br label [[CLEANUP4]]
 // CHECK-EH-11:       cleanup4:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    br i1 [[CMP1]], label [[RETURN]], label [[CLEANUP_CONT7:%.*]]
-// CHECK-EH-11:       cleanup.cont7.critedge:
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    br label [[CLEANUP_CONT7]]
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP8]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[CLEANUP_DEST6:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4
+// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST6]], label [[UNREACHABLE]] [
+// CHECK-EH-11-NEXT:    i32 0, label [[CLEANUP_CONT7:%.*]]
+// CHECK-EH-11-NEXT:    i32 1, label [[RETURN]]
+// CHECK-EH-11-NEXT:    ]
 // CHECK-EH-11:       cleanup.cont7:
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]]
 // CHECK-EH-11:       invoke.cont9:
+// CHECK-EH-11-NEXT:    store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP10]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       lpad8:
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP11:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP14:%.*]] = bitcast %class.X* [[Z]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP14]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[EH_RESUME]]
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       eh.resume:
-// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD8]] ], [ [[TMP1]], [[LPAD]] ]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN]]
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL12:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL12]]
+// CHECK-EH-11:       unreachable:
+// CHECK-EH-11-NEXT:    unreachable
 //
 X test18(int i) { // http://wg21.link/p2025r2#ex-11
   {
@@ -1501,22 +2961,57 @@ X test18(int i) { // http://wg21.link/p2025r2#ex-11
 #ifdef CXX11
 // CHECK-EH-11-LABEL: @_Z6test19v(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-EH-11-NEXT:    [[L:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[L]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[L]])
+// CHECK-EH-11-NEXT:    [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 4
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[L]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.anon.0* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 0
+// CHECK-EH-11-NEXT:    store %class.X* [[AGG_RESULT]], %class.X** [[TMP3]], align 4, !tbaa [[TBAA8]]
+// CHECK-EH-11-NEXT:    invoke void @"_ZZ6test19vENK3$_1clEv"(%class.X* sret([[CLASS_X]]) align 1 [[L]], %class.anon.0* noundef nonnull align 4 dereferenceable(4) [[REF_TMP]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = bitcast %class.anon.0* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[L]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = bitcast %class.X* [[L]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP5]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = extractvalue { i8*, i32 } [[TMP6]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP7]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP6]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP8]], i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = bitcast %class.anon.0* [[REF_TMP]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP9]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = bitcast %class.X* [[L]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP10]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       nrvo.unused:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test19() { // http://wg21.link/p2025r2#ex-12
   X x;
@@ -1542,42 +3037,11 @@ X test20() { // http://wg21.link/p2025r2#ex-18
 
 // CHECK-EH-11-LABEL: @_Z17test20instantiatev(
 // CHECK-EH-11-NEXT:  entry:
-// CHECK-EH-11-NEXT:    [[X_I2:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    [[X_I:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X]], align 1
+// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]), !noalias !6
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]])
-// CHECK-EH-11-NEXT:    to label [[_Z6TEST20ILB1EE1XV_EXIT:%.*]] unwind label [[LPAD_I:%.*]]
-// CHECK-EH-11:       common.resume:
-// CHECK-EH-11-NEXT:    [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[TMP1:%.*]], [[LPAD_I]] ], [ [[TMP3:%.*]], [[LPAD_I3:%.*]] ]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[COMMON_RESUME_OP]]
-// CHECK-EH-11:       lpad.i:
-// CHECK-EH-11-NEXT:    [[TMP1]] = landingpad { i8*, i32 }
-// CHECK-EH-11-NEXT:    cleanup
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6
-// CHECK-EH-11-NEXT:    br label [[COMMON_RESUME:%.*]]
-// CHECK-EH-11:       _Z6test20ILb1EE1Xv.exit:
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6
+// CHECK-EH-11-NEXT:    call void @_Z6test20ILb1EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]])
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I2]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]), !noalias !9
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]])
-// CHECK-EH-11-NEXT:    to label [[_Z6TEST20ILB0EE1XV_EXIT:%.*]] unwind label [[LPAD_I3]]
-// CHECK-EH-11:       lpad.i3:
-// CHECK-EH-11-NEXT:    [[TMP3]] = landingpad { i8*, i32 }
-// CHECK-EH-11-NEXT:    cleanup
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9
-// CHECK-EH-11-NEXT:    br label [[COMMON_RESUME]]
-// CHECK-EH-11:       _Z6test20ILb0EE1Xv.exit:
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9
+// CHECK-EH-11-NEXT:    call void @_Z6test20ILb0EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]])
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 //
@@ -1589,13 +3053,54 @@ void test20instantiate() {
 
 // CHECK-LABEL: @_Z6test21v(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
 // CHECK-NEXT:    ret void
 //
-// CHECK-EH-LABEL: @_Z6test21v(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z6test21v(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z6test21v(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    ret void
 //
 const volatile X test21() { // http://wg21.link/p2025r2#ex-19
   X x;
@@ -1604,60 +3109,98 @@ const volatile X test21() { // http://wg21.link/p2025r2#ex-19
 
 // CHECK-LABEL: @_Z6test22v(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test22v(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    ret void
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL2]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP8]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test22v(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
 // CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
+// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast %class.X* [[X]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP6]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test22() { // http://wg21.link/p2025r2#ex-19
   volatile X x;
@@ -1666,81 +3209,161 @@ X test22() { // http://wg21.link/p2025r2#ex-19
 
 // CHECK-LABEL: @_Z6test23b(
 // CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK:       if.then:
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
+// CHECK-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK:       nrvo.unused:
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]
+// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK:       nrvo.skipdtor:
 // CHECK-NEXT:    br label [[RETURN:%.*]]
 // CHECK:       if.end:
-// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
-// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR4]]
+// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
+// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR4]]
 // CHECK-NEXT:    br label [[RETURN]]
 // CHECK:       return:
 // CHECK-NEXT:    ret void
 //
 // CHECK-EH-03-LABEL: @_Z6test23b(
 // CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-03-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-03-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-03-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-03:       if.then:
-// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
 // CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-03:       if.end:
-// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont:
 // CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR6]]
 // CHECK-EH-03-NEXT:    br label [[RETURN]]
 // CHECK-EH-03:       lpad:
-// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    cleanup
+// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-03-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-03-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
 // CHECK-EH-03:       invoke.cont1:
-// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR6]]
+// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       return:
 // CHECK-EH-03-NEXT:    ret void
+// CHECK-EH-03:       eh.resume:
+// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL2]]
 // CHECK-EH-03:       terminate.lpad:
-// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-03-NEXT:    catch i8* null
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
-// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
+// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0
+// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP9]]) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    unreachable
 //
 // CHECK-EH-11-LABEL: @_Z6test23b(
 // CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
 // CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8
+// CHECK-EH-11-NEXT:    store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]]
+// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1, !tbaa [[TBAA3]], !range [[RNG7]]
+// CHECK-EH-11-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-EH-11-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 // CHECK-EH-11:       if.then:
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
 // CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
 // CHECK-EH-11:       if.end:
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP2]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
 // CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 // CHECK-EH-11:       invoke.cont:
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP3]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    br label [[RETURN]]
 // CHECK-EH-11:       lpad:
-// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
 // CHECK-EH-11-NEXT:    cleanup
+// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0
+// CHECK-EH-11-NEXT:    store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1
+// CHECK-EH-11-NEXT:    store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
+// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = bitcast %class.X* [[Y]] to i8*
+// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* [[TMP7]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       return:
 // CHECK-EH-11-NEXT:    ret void
+// CHECK-EH-11:       eh.resume:
+// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4
+// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0
+// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1
+// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL1]]
 //
 X test23(bool b) { // http://wg21.link/p2025r2#ex-19
   if (b) {
@@ -1752,10 +3375,39 @@ X test23(bool b) { // http://wg21.link/p2025r2#ex-19
 }
 
 #ifdef __EXCEPTIONS
-// CHECK-EH-LABEL: @_Z6test24v(
-// CHECK-EH-NEXT:  entry:
-// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
-// CHECK-EH-NEXT:    ret void
+// CHECK-EH-03-LABEL: @_Z6test24v(
+// CHECK-EH-03-NEXT:  entry:
+// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-03-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-03-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-03:       nrvo.unused:
+// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-03:       nrvo.skipdtor:
+// CHECK-EH-03-NEXT:    ret void
+//
+// CHECK-EH-11-LABEL: @_Z6test24v(
+// CHECK-EH-11-NEXT:  entry:
+// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca i8*, align 4
+// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1
+// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8*
+// CHECK-EH-11-NEXT:    store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4
+// CHECK-EH-11-NEXT:    store i1 false, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
+// CHECK-EH-11-NEXT:    store i1 true, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1
+// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]
+// CHECK-EH-11:       nrvo.unused:
+// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
+// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]
+// CHECK-EH-11:       nrvo.skipdtor:
+// CHECK-EH-11-NEXT:    ret void
 //
 X test24() { // http://wg21.link/p2025r2#ex-20
   X x;
@@ -1778,42 +3430,11 @@ X test25() {
 
 // CHECK-EH-11-LABEL: @_Z17test25instantiatev(
 // CHECK-EH-11-NEXT:  entry:
-// CHECK-EH-11-NEXT:    [[X_I2:%.*]] = alloca [[CLASS_X:%.*]], align 1
-// CHECK-EH-11-NEXT:    [[X_I:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X]], align 1
+// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1
 // CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1
-// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]), !noalias !12
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]])
-// CHECK-EH-11-NEXT:    to label [[_Z6TEST25ILB1EE1XV_EXIT:%.*]] unwind label [[LPAD_I:%.*]]
-// CHECK-EH-11:       common.resume:
-// CHECK-EH-11-NEXT:    [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[TMP1:%.*]], [[LPAD_I]] ], [ [[TMP3:%.*]], [[LPAD_I3:%.*]] ]
-// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[COMMON_RESUME_OP]]
-// CHECK-EH-11:       lpad.i:
-// CHECK-EH-11-NEXT:    [[TMP1]] = landingpad { i8*, i32 }
-// CHECK-EH-11-NEXT:    cleanup
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12
-// CHECK-EH-11-NEXT:    br label [[COMMON_RESUME:%.*]]
-// CHECK-EH-11:       _Z6test25ILb1EE1Xv.exit:
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12
+// CHECK-EH-11-NEXT:    call void @_Z6test25ILb1EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]])
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I2]], i32 0, i32 0
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15
-// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]), !noalias !15
-// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]])
-// CHECK-EH-11-NEXT:    to label [[_Z6TEST25ILB0EE1XV_EXIT:%.*]] unwind label [[LPAD_I3]]
-// CHECK-EH-11:       lpad.i3:
-// CHECK-EH-11-NEXT:    [[TMP3]] = landingpad { i8*, i32 }
-// CHECK-EH-11-NEXT:    cleanup
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15
-// CHECK-EH-11-NEXT:    br label [[COMMON_RESUME]]
-// CHECK-EH-11:       _Z6test25ILb0EE1Xv.exit:
-// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]]
-// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15
+// CHECK-EH-11-NEXT:    call void @_Z6test25ILb0EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]])
 // CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR7]]
 // CHECK-EH-11-NEXT:    ret void
 //


        


More information about the cfe-commits mailing list