brintos

brintos / llvm-project-archived public Read only

0
0
Text · 163.3 KiB · 5b0fc91 Raw
2948 lines · cpp
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py2// RUN: %clang_cc1 -triple i386-unknown-unknown -Wno-error=return-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s3// RUN: %clang_cc1 -triple i386-unknown-unknown -Wno-error=return-type -emit-llvm -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH-03 %s4// RUN: %clang_cc1 -triple i386-unknown-unknown -Wno-error=return-type -emit-llvm -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++11 -DCXX11 -o - %s | FileCheck --check-prefixes=CHECK-EH-11 %s5 6// Test code generation for the named return value optimization.7class X {8public:9  X();10  X(const X&);11  X(const volatile X &);12  ~X();13};14 15template<typename T> struct Y {16  Y();17  static Y f() {18    Y y;19    return y;20  }21};22 23void ConsumeX(X x);24extern X OuterX;25 26// CHECK-LABEL: @_Z5test0v(27// CHECK-NEXT:  entry:28// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 429// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 130// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 431// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 132// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])33// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 134// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 135// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]36// CHECK:       nrvo.unused:37// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4:[0-9]+]]38// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]39// CHECK:       nrvo.skipdtor:40// CHECK-NEXT:    ret void41//42// CHECK-EH-03-LABEL: @_Z5test0v(43// CHECK-EH-03-NEXT:  entry:44// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 445// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 146// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 447// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 148// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])49// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 150// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 151// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]52// CHECK-EH-03:       nrvo.unused:53// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])54// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]55// CHECK-EH-03:       nrvo.skipdtor:56// CHECK-EH-03-NEXT:    ret void57//58// CHECK-EH-11-LABEL: @_Z5test0v(59// CHECK-EH-11-NEXT:  entry:60// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 461// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 162// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 463// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 164// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])65// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 166// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 167// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]68// CHECK-EH-11:       nrvo.unused:69// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6:[0-9]+]]70// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]71// CHECK-EH-11:       nrvo.skipdtor:72// CHECK-EH-11-NEXT:    ret void73//74X test0() { // http://wg21.link/p2025r2#ex-275  X x;76  return x; // NRVO happens77}78 79// CHECK-LABEL: @_Z5test1b(80// CHECK-NEXT:  entry:81// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 482// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 183// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 184// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 485// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 486// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i887// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 188// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 189// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])90// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 191// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i192// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]93// CHECK:       if.then:94// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 195// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 496// CHECK-NEXT:    br label [[CLEANUP:%.*]]97// CHECK:       if.end:98// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 199// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4100// CHECK-NEXT:    br label [[CLEANUP]]101// CHECK:       cleanup:102// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1103// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]104// CHECK:       nrvo.unused:105// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]106// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]107// CHECK:       nrvo.skipdtor:108// CHECK-NEXT:    ret void109//110// CHECK-EH-03-LABEL: @_Z5test1b(111// CHECK-EH-03-NEXT:  entry:112// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4113// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1114// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1115// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4116// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4117// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8118// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1119// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 1120// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])121// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1122// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1123// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]124// CHECK-EH-03:       if.then:125// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1126// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4127// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]128// CHECK-EH-03:       if.end:129// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1130// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4131// CHECK-EH-03-NEXT:    br label [[CLEANUP]]132// CHECK-EH-03:       cleanup:133// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1134// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]135// CHECK-EH-03:       nrvo.unused:136// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])137// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]138// CHECK-EH-03:       nrvo.skipdtor:139// CHECK-EH-03-NEXT:    ret void140//141// CHECK-EH-11-LABEL: @_Z5test1b(142// CHECK-EH-11-NEXT:  entry:143// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4144// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1145// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1146// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4147// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4148// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8149// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1150// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 1151// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])152// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1153// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1154// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]155// CHECK-EH-11:       if.then:156// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 1157// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4158// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]159// CHECK-EH-11:       if.end:160// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 1161// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4162// CHECK-EH-11-NEXT:    br label [[CLEANUP]]163// CHECK-EH-11:       cleanup:164// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1165// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]166// CHECK-EH-11:       nrvo.unused:167// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]168// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]169// CHECK-EH-11:       nrvo.skipdtor:170// CHECK-EH-11-NEXT:    ret void171//172X test1(bool B) {173  X x;174  if (B)175    return (x); // NRVO happens176  return x;     // NRVO happens177}178 179// CHECK-LABEL: @_Z5test2b(180// CHECK-NEXT:  entry:181// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4182// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1183// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1184// CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1185// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4186// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4187// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8188// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1189// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])190// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])191// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1192// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1193// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]194// CHECK:       if.then:195// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])196// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4197// CHECK-NEXT:    br label [[CLEANUP:%.*]]198// CHECK:       if.end:199// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])200// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4201// CHECK-NEXT:    br label [[CLEANUP]]202// CHECK:       cleanup:203// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]204// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]205// CHECK-NEXT:    ret void206//207// CHECK-EH-03-LABEL: @_Z5test2b(208// CHECK-EH-03-NEXT:  entry:209// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4210// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1211// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1212// CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1213// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4214// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4215// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4216// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4217// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8218// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1219// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])220// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])221// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]222// CHECK-EH-03:       invoke.cont:223// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1224// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1225// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]226// CHECK-EH-03:       if.then:227// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])228// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]229// CHECK-EH-03:       invoke.cont2:230// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4231// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]232// CHECK-EH-03:       lpad:233// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }234// CHECK-EH-03-NEXT:            cleanup235// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0236// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4237// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1238// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4239// CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]240// CHECK-EH-03:       lpad1:241// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }242// CHECK-EH-03-NEXT:            cleanup243// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0244// CHECK-EH-03-NEXT:    store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4245// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1246// CHECK-EH-03-NEXT:    store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4247// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])248// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]]249// CHECK-EH-03:       if.end:250// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])251// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]]252// CHECK-EH-03:       invoke.cont3:253// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4254// CHECK-EH-03-NEXT:    br label [[CLEANUP]]255// CHECK-EH-03:       cleanup:256// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])257// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]]258// CHECK-EH-03:       invoke.cont4:259// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])260// CHECK-EH-03-NEXT:    ret void261// CHECK-EH-03:       invoke.cont5:262// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]263// CHECK-EH-03:       ehcleanup:264// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])265// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]]266// CHECK-EH-03:       invoke.cont7:267// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]268// CHECK-EH-03:       eh.resume:269// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4270// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4271// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0272// CHECK-EH-03-NEXT:    [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1273// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL8]]274// CHECK-EH-03:       terminate.lpad:275// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = landingpad { ptr, i32 }276// CHECK-EH-03-NEXT:            catch ptr null277// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0278// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP8]]) #[[ATTR6:[0-9]+]]279// CHECK-EH-03-NEXT:    unreachable280//281// CHECK-EH-11-LABEL: @_Z5test2b(282// CHECK-EH-11-NEXT:  entry:283// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4284// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1285// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1286// CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1287// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4288// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4289// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4290// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4291// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8292// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1293// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])294// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])295// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]296// CHECK-EH-11:       invoke.cont:297// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1298// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1299// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]300// CHECK-EH-11:       if.then:301// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])302// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]303// CHECK-EH-11:       invoke.cont2:304// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4305// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]306// CHECK-EH-11:       lpad:307// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }308// CHECK-EH-11-NEXT:            cleanup309// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0310// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4311// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1312// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4313// CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]314// CHECK-EH-11:       lpad1:315// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }316// CHECK-EH-11-NEXT:            cleanup317// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0318// CHECK-EH-11-NEXT:    store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4319// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1320// CHECK-EH-11-NEXT:    store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4321// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]]322// CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]323// CHECK-EH-11:       if.end:324// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])325// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]]326// CHECK-EH-11:       invoke.cont3:327// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4328// CHECK-EH-11-NEXT:    br label [[CLEANUP]]329// CHECK-EH-11:       cleanup:330// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]]331// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]332// CHECK-EH-11-NEXT:    ret void333// CHECK-EH-11:       ehcleanup:334// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]335// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]336// CHECK-EH-11:       eh.resume:337// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4338// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4339// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0340// CHECK-EH-11-NEXT:    [[LPAD_VAL5:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1341// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL5]]342//343X test2(bool B) {344  X x;345  X y;346  if (B)347    return y; // NRVO is impossible348  return x;   // NRVO is impossible349}350 351// CHECK-LABEL: @_Z5test3b(352// CHECK-NEXT:  entry:353// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4354// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1355// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1356// CHECK-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1357// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4358// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8359// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1360// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1361// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1362// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]363// CHECK:       if.then:364// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 1365// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])366// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 1367// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1368// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]369// CHECK:       nrvo.unused:370// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]371// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]372// CHECK:       nrvo.skipdtor:373// CHECK-NEXT:    br label [[RETURN:%.*]]374// CHECK:       if.end:375// CHECK-NEXT:    store i1 false, ptr [[NRVO1]], align 1376// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])377// CHECK-NEXT:    store i1 true, ptr [[NRVO1]], align 1378// CHECK-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1379// CHECK-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]380// CHECK:       nrvo.unused3:381// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]382// CHECK-NEXT:    br label [[NRVO_SKIPDTOR4]]383// CHECK:       nrvo.skipdtor4:384// CHECK-NEXT:    br label [[RETURN]]385// CHECK:       return:386// CHECK-NEXT:    ret void387//388// CHECK-EH-03-LABEL: @_Z5test3b(389// CHECK-EH-03-NEXT:  entry:390// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4391// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1392// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1393// CHECK-EH-03-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1394// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4395// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8396// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1397// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1398// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1399// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]400// CHECK-EH-03:       if.then:401// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 1402// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])403// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1404// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1405// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]406// CHECK-EH-03:       nrvo.unused:407// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])408// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]409// CHECK-EH-03:       nrvo.skipdtor:410// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]411// CHECK-EH-03:       if.end:412// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO1]], align 1413// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])414// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO1]], align 1415// CHECK-EH-03-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1416// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]417// CHECK-EH-03:       nrvo.unused3:418// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])419// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR4]]420// CHECK-EH-03:       nrvo.skipdtor4:421// CHECK-EH-03-NEXT:    br label [[RETURN]]422// CHECK-EH-03:       return:423// CHECK-EH-03-NEXT:    ret void424//425// CHECK-EH-11-LABEL: @_Z5test3b(426// CHECK-EH-11-NEXT:  entry:427// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4428// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1429// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1430// CHECK-EH-11-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1431// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4432// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8433// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1434// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1435// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1436// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]437// CHECK-EH-11:       if.then:438// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 1439// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])440// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 1441// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1442// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]443// CHECK-EH-11:       nrvo.unused:444// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]445// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]446// CHECK-EH-11:       nrvo.skipdtor:447// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]448// CHECK-EH-11:       if.end:449// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO1]], align 1450// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])451// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO1]], align 1452// CHECK-EH-11-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1453// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]454// CHECK-EH-11:       nrvo.unused3:455// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]456// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR4]]457// CHECK-EH-11:       nrvo.skipdtor4:458// CHECK-EH-11-NEXT:    br label [[RETURN]]459// CHECK-EH-11:       return:460// CHECK-EH-11-NEXT:    ret void461//462X test3(bool B) { // http://wg21.link/p2025r2#ex-4463  if (B) {464    X y;465    return y; // NRVO happens466  }467  X x;468  return x; // FIXME: NRVO could happen, but doesn't469}470 471extern "C" void exit(int) throw();472 473// CHECK-LABEL: @_Z5test4b(474// CHECK-NEXT:  entry:475// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4476// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1477// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1478// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4479// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4480// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8481// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1482// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 1483// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])484// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1485// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1486// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]487// CHECK:       if.then:488// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 1489// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4490// CHECK-NEXT:    br label [[CLEANUP:%.*]]491// CHECK:       if.end:492// CHECK-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4493// CHECK-NEXT:    br label [[CLEANUP]]494// CHECK:       cleanup:495// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1496// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]497// CHECK:       nrvo.unused:498// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]499// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]500// CHECK:       nrvo.skipdtor:501// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4502// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [503// CHECK-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]504// CHECK-NEXT:      i32 1, label [[RETURN:%.*]]505// CHECK-NEXT:    ]506// CHECK:       cleanup.cont:507// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR4]]508// CHECK-NEXT:    call void @llvm.trap()509// CHECK-NEXT:    unreachable510// CHECK:       return:511// CHECK-NEXT:    ret void512// CHECK:       unreachable:513// CHECK-NEXT:    unreachable514//515// CHECK-EH-03-LABEL: @_Z5test4b(516// CHECK-EH-03-NEXT:  entry:517// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4518// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1519// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1520// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4521// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4522// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8523// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1524// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 1525// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])526// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1527// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1528// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]529// CHECK-EH-03:       if.then:530// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1531// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4532// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]533// CHECK-EH-03:       if.end:534// CHECK-EH-03-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4535// CHECK-EH-03-NEXT:    br label [[CLEANUP]]536// CHECK-EH-03:       cleanup:537// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1538// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]539// CHECK-EH-03:       nrvo.unused:540// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])541// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]542// CHECK-EH-03:       nrvo.skipdtor:543// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4544// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [545// CHECK-EH-03-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]546// CHECK-EH-03-NEXT:      i32 1, label [[RETURN:%.*]]547// CHECK-EH-03-NEXT:    ]548// CHECK-EH-03:       cleanup.cont:549// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7:[0-9]+]]550// CHECK-EH-03-NEXT:    call void @llvm.trap()551// CHECK-EH-03-NEXT:    unreachable552// CHECK-EH-03:       return:553// CHECK-EH-03-NEXT:    ret void554// CHECK-EH-03:       unreachable:555// CHECK-EH-03-NEXT:    unreachable556//557// CHECK-EH-11-LABEL: @_Z5test4b(558// CHECK-EH-11-NEXT:  entry:559// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4560// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1561// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1562// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4563// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4564// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8565// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1566// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 1567// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])568// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1569// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1570// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]571// CHECK-EH-11:       if.then:572// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 1573// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4574// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]575// CHECK-EH-11:       if.end:576// CHECK-EH-11-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4577// CHECK-EH-11-NEXT:    br label [[CLEANUP]]578// CHECK-EH-11:       cleanup:579// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1580// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]581// CHECK-EH-11:       nrvo.unused:582// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]583// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]584// CHECK-EH-11:       nrvo.skipdtor:585// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4586// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [587// CHECK-EH-11-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]588// CHECK-EH-11-NEXT:      i32 1, label [[RETURN:%.*]]589// CHECK-EH-11-NEXT:    ]590// CHECK-EH-11:       cleanup.cont:591// CHECK-EH-11-NEXT:    call void @exit(i32 noundef 1) #[[ATTR6]]592// CHECK-EH-11-NEXT:    call void @llvm.trap()593// CHECK-EH-11-NEXT:    unreachable594// CHECK-EH-11:       return:595// CHECK-EH-11-NEXT:    ret void596// CHECK-EH-11:       unreachable:597// CHECK-EH-11-NEXT:    unreachable598//599X test4(bool B) {600  {601    X x;602    if (B)603      return x; // NRVO happens604  }605  exit(1);606}607 608#ifdef __EXCEPTIONS609void may_throw();610// CHECK-EH-03-LABEL: @_Z5test5v(611// CHECK-EH-03-NEXT:  entry:612// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4613// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4614// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4615// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1616// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4617// CHECK-EH-03-NEXT:    invoke void @_Z9may_throwv()618// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]619// CHECK-EH-03:       invoke.cont:620// CHECK-EH-03-NEXT:    br label [[TRY_CONT:%.*]]621// CHECK-EH-03:       lpad:622// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }623// CHECK-EH-03-NEXT:            catch ptr @_ZTI1X624// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0625// CHECK-EH-03-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4626// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1627// CHECK-EH-03-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4628// CHECK-EH-03-NEXT:    br label [[CATCH_DISPATCH:%.*]]629// CHECK-EH-03:       catch.dispatch:630// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4631// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR7]]632// CHECK-EH-03-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]633// CHECK-EH-03-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]634// CHECK-EH-03:       catch:635// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4636// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR7]]637// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]])638// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]639// CHECK-EH-03:       invoke.cont1:640// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR7]]641// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])642// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]643// CHECK-EH-03:       invoke.cont3:644// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])645// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]]646// CHECK-EH-03:       lpad2:647// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = landingpad { ptr, i32 }648// CHECK-EH-03-NEXT:            cleanup649// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0650// CHECK-EH-03-NEXT:    store ptr [[TMP7]], ptr [[EXN_SLOT]], align 4651// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1652// CHECK-EH-03-NEXT:    store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4653// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])654// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD]]655// CHECK-EH-03:       invoke.cont5:656// CHECK-EH-03-NEXT:    call void @__cxa_end_catch()657// CHECK-EH-03-NEXT:    ret void658// CHECK-EH-03:       lpad4:659// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = landingpad { ptr, i32 }660// CHECK-EH-03-NEXT:            cleanup661// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = extractvalue { ptr, i32 } [[TMP9]], 0662// CHECK-EH-03-NEXT:    store ptr [[TMP10]], ptr [[EXN_SLOT]], align 4663// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { ptr, i32 } [[TMP9]], 1664// CHECK-EH-03-NEXT:    store i32 [[TMP11]], ptr [[EHSELECTOR_SLOT]], align 4665// CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]666// CHECK-EH-03:       invoke.cont6:667// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]668// CHECK-EH-03:       ehcleanup:669// CHECK-EH-03-NEXT:    invoke void @__cxa_end_catch()670// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]]671// CHECK-EH-03:       invoke.cont7:672// CHECK-EH-03-NEXT:    br label [[EH_RESUME]]673// CHECK-EH-03:       try.cont:674// CHECK-EH-03-NEXT:    call void @llvm.trap()675// CHECK-EH-03-NEXT:    unreachable676// CHECK-EH-03:       eh.resume:677// CHECK-EH-03-NEXT:    [[EXN8:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4678// CHECK-EH-03-NEXT:    [[SEL9:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4679// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN8]], 0680// CHECK-EH-03-NEXT:    [[LPAD_VAL10:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL9]], 1681// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL10]]682// CHECK-EH-03:       terminate.lpad:683// CHECK-EH-03-NEXT:    [[TMP12:%.*]] = landingpad { ptr, i32 }684// CHECK-EH-03-NEXT:            catch ptr null685// CHECK-EH-03-NEXT:    [[TMP13:%.*]] = extractvalue { ptr, i32 } [[TMP12]], 0686// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP13]]) #[[ATTR6]]687// CHECK-EH-03-NEXT:    unreachable688//689// CHECK-EH-11-LABEL: @_Z5test5v(690// CHECK-EH-11-NEXT:  entry:691// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4692// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4693// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4694// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1695// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4696// CHECK-EH-11-NEXT:    invoke void @_Z9may_throwv()697// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]698// CHECK-EH-11:       invoke.cont:699// CHECK-EH-11-NEXT:    br label [[TRY_CONT:%.*]]700// CHECK-EH-11:       lpad:701// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }702// CHECK-EH-11-NEXT:            catch ptr @_ZTI1X703// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0704// CHECK-EH-11-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4705// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1706// CHECK-EH-11-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4707// CHECK-EH-11-NEXT:    br label [[CATCH_DISPATCH:%.*]]708// CHECK-EH-11:       catch.dispatch:709// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4710// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR6]]711// CHECK-EH-11-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]712// CHECK-EH-11-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]713// CHECK-EH-11:       catch:714// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4715// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR6]]716// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]])717// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]718// CHECK-EH-11:       invoke.cont1:719// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR6]]720// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])721// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]722// CHECK-EH-11:       invoke.cont3:723// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]724// CHECK-EH-11-NEXT:    call void @__cxa_end_catch()725// CHECK-EH-11-NEXT:    ret void726// CHECK-EH-11:       lpad2:727// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = landingpad { ptr, i32 }728// CHECK-EH-11-NEXT:            cleanup729// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0730// CHECK-EH-11-NEXT:    store ptr [[TMP7]], ptr [[EXN_SLOT]], align 4731// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1732// CHECK-EH-11-NEXT:    store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4733// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]734// CHECK-EH-11-NEXT:    invoke void @__cxa_end_catch()735// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]]736// CHECK-EH-11:       invoke.cont4:737// CHECK-EH-11-NEXT:    br label [[EH_RESUME]]738// CHECK-EH-11:       try.cont:739// CHECK-EH-11-NEXT:    call void @llvm.trap()740// CHECK-EH-11-NEXT:    unreachable741// CHECK-EH-11:       eh.resume:742// CHECK-EH-11-NEXT:    [[EXN5:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4743// CHECK-EH-11-NEXT:    [[SEL6:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4744// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN5]], 0745// CHECK-EH-11-NEXT:    [[LPAD_VAL7:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL6]], 1746// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL7]]747// CHECK-EH-11:       terminate.lpad:748// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = landingpad { ptr, i32 }749// CHECK-EH-11-NEXT:            catch ptr null750// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { ptr, i32 } [[TMP9]], 0751// CHECK-EH-11-NEXT:    call void @__clang_call_terminate(ptr [[TMP10]]) #[[ATTR7:[0-9]+]]752// CHECK-EH-11-NEXT:    unreachable753//754X test5() { // http://wg21.link/p2025r2#ex-14755  try {756    may_throw();757  } catch (X x) {758    return x; // FIXME: NRVO could happen, but doesn't759  }760}761#endif762 763// CHECK-LABEL: @_Z5test6v(764// CHECK-NEXT:  entry:765// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4766// CHECK-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8767// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4768// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]])769// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]])770// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR4]]771// CHECK-NEXT:    ret void772//773// CHECK-EH-03-LABEL: @_Z5test6v(774// CHECK-EH-03-NEXT:  entry:775// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4776// CHECK-EH-03-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8777// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4778// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4779// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4780// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]])781// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]])782// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]783// CHECK-EH-03:       invoke.cont:784// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]])785// CHECK-EH-03-NEXT:    ret void786// CHECK-EH-03:       lpad:787// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }788// CHECK-EH-03-NEXT:            cleanup789// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0790// CHECK-EH-03-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4791// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1792// CHECK-EH-03-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4793// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]])794// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]795// CHECK-EH-03:       invoke.cont1:796// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]797// CHECK-EH-03:       eh.resume:798// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4799// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4800// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0801// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1802// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]803// CHECK-EH-03:       terminate.lpad:804// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { ptr, i32 }805// CHECK-EH-03-NEXT:            catch ptr null806// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0807// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP4]]) #[[ATTR6]]808// CHECK-EH-03-NEXT:    unreachable809//810// CHECK-EH-11-LABEL: @_Z5test6v(811// CHECK-EH-11-NEXT:  entry:812// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4813// CHECK-EH-11-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8814// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 4815// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4816// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4817// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]])818// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]])819// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]820// CHECK-EH-11:       invoke.cont:821// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR6]]822// CHECK-EH-11-NEXT:    ret void823// CHECK-EH-11:       lpad:824// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }825// CHECK-EH-11-NEXT:            cleanup826// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0827// CHECK-EH-11-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4828// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1829// CHECK-EH-11-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4830// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR6]]831// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]832// CHECK-EH-11:       eh.resume:833// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4834// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4835// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0836// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1837// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL1]]838//839X test6() {840  X a __attribute__((aligned(8)));841  return a; // NRVO is impossible842}843 844// CHECK-LABEL: @_Z5test7b(845// CHECK-NEXT:  entry:846// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4847// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1848// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1849// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4850// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8851// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1852// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1853// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1854// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]855// CHECK:       if.then:856// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 1857// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])858// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 1859// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1860// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]861// CHECK:       nrvo.unused:862// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]863// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]864// CHECK:       nrvo.skipdtor:865// CHECK-NEXT:    br label [[RETURN:%.*]]866// CHECK:       if.end:867// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])868// CHECK-NEXT:    br label [[RETURN]]869// CHECK:       return:870// CHECK-NEXT:    ret void871//872// CHECK-EH-03-LABEL: @_Z5test7b(873// CHECK-EH-03-NEXT:  entry:874// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4875// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1876// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1877// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4878// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8879// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1880// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1881// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1882// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]883// CHECK-EH-03:       if.then:884// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 1885// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])886// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1887// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1888// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]889// CHECK-EH-03:       nrvo.unused:890// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])891// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]892// CHECK-EH-03:       nrvo.skipdtor:893// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]894// CHECK-EH-03:       if.end:895// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])896// CHECK-EH-03-NEXT:    br label [[RETURN]]897// CHECK-EH-03:       return:898// CHECK-EH-03-NEXT:    ret void899//900// CHECK-EH-11-LABEL: @_Z5test7b(901// CHECK-EH-11-NEXT:  entry:902// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4903// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1904// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 1905// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4906// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8907// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1908// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1909// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1910// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]911// CHECK-EH-11:       if.then:912// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 1913// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])914// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 1915// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1916// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]917// CHECK-EH-11:       nrvo.unused:918// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]919// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]920// CHECK-EH-11:       nrvo.skipdtor:921// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]922// CHECK-EH-11:       if.end:923// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])924// CHECK-EH-11-NEXT:    br label [[RETURN]]925// CHECK-EH-11:       return:926// CHECK-EH-11-NEXT:    ret void927//928X test7(bool b) {929  if (b) {930    X x;931    return x; // NRVO happens932  }933  return X();934}935 936// CHECK-LABEL: @_Z5test8b(937// CHECK-NEXT:  entry:938// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4939// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1940// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 1941// CHECK-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1942// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4943// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8944// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1945// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1946// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1947// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]948// CHECK:       if.then:949// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 1950// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])951// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 1952// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1953// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]954// CHECK:       nrvo.unused:955// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]956// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]957// CHECK:       nrvo.skipdtor:958// CHECK-NEXT:    br label [[RETURN:%.*]]959// CHECK:       if.else:960// CHECK-NEXT:    store i1 false, ptr [[NRVO1]], align 1961// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])962// CHECK-NEXT:    store i1 true, ptr [[NRVO1]], align 1963// CHECK-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1964// CHECK-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]965// CHECK:       nrvo.unused3:966// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]967// CHECK-NEXT:    br label [[NRVO_SKIPDTOR4]]968// CHECK:       nrvo.skipdtor4:969// CHECK-NEXT:    br label [[RETURN]]970// CHECK:       return:971// CHECK-NEXT:    ret void972//973// CHECK-EH-03-LABEL: @_Z5test8b(974// CHECK-EH-03-NEXT:  entry:975// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4976// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 1977// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 1978// CHECK-EH-03-NEXT:    [[NRVO1:%.*]] = alloca i1, align 1979// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4980// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i8981// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 1982// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1983// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1984// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]985// CHECK-EH-03:       if.then:986// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 1987// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])988// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 1989// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1990// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]991// CHECK-EH-03:       nrvo.unused:992// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])993// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]994// CHECK-EH-03:       nrvo.skipdtor:995// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]996// CHECK-EH-03:       if.else:997// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO1]], align 1998// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])999// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO1]], align 11000// CHECK-EH-03-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 11001// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]1002// CHECK-EH-03:       nrvo.unused3:1003// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1004// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR4]]1005// CHECK-EH-03:       nrvo.skipdtor4:1006// CHECK-EH-03-NEXT:    br label [[RETURN]]1007// CHECK-EH-03:       return:1008// CHECK-EH-03-NEXT:    ret void1009//1010// CHECK-EH-11-LABEL: @_Z5test8b(1011// CHECK-EH-11-NEXT:  entry:1012// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41013// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11014// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 11015// CHECK-EH-11-NEXT:    [[NRVO1:%.*]] = alloca i1, align 11016// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41017// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81018// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11019// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11020// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11021// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1022// CHECK-EH-11:       if.then:1023// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 11024// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1025// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 11026// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11027// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1028// CHECK-EH-11:       nrvo.unused:1029// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1030// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]1031// CHECK-EH-11:       nrvo.skipdtor:1032// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]1033// CHECK-EH-11:       if.else:1034// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO1]], align 11035// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1036// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO1]], align 11037// CHECK-EH-11-NEXT:    [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 11038// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]]1039// CHECK-EH-11:       nrvo.unused3:1040// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1041// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR4]]1042// CHECK-EH-11:       nrvo.skipdtor4:1043// CHECK-EH-11-NEXT:    br label [[RETURN]]1044// CHECK-EH-11:       return:1045// CHECK-EH-11-NEXT:    ret void1046//1047X test8(bool b) {1048  if (b) {1049    X x;1050    return x; // NRVO happens1051  } else {1052    X y;1053    return y; // NRVO happens1054  }1055}1056 1057// CHECK-LABEL: @_Z5test9v(1058// CHECK-NEXT:  entry:1059// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41060// CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 11061// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41062// CHECK-NEXT:    call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]])1063// CHECK-NEXT:    call void @llvm.trap()1064// CHECK-NEXT:    unreachable1065//1066// CHECK-EH-03-LABEL: @_Z5test9v(1067// CHECK-EH-03-NEXT:  entry:1068// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41069// CHECK-EH-03-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 11070// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41071// CHECK-EH-03-NEXT:    call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]])1072// CHECK-EH-03-NEXT:    call void @llvm.trap()1073// CHECK-EH-03-NEXT:    unreachable1074//1075// CHECK-EH-11-LABEL: @_Z5test9v(1076// CHECK-EH-11-NEXT:  entry:1077// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41078// CHECK-EH-11-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 11079// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41080// CHECK-EH-11-NEXT:    call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]])1081// CHECK-EH-11-NEXT:    call void @llvm.trap()1082// CHECK-EH-11-NEXT:    unreachable1083//1084Y<int> test9() {1085  Y<int>::f();1086}1087 1088// CHECK-LABEL: @_Z6test10b(1089// CHECK-NEXT:  entry:1090// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41091// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11092// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11093// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41094// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41095// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81096// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11097// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1098// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11099// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11100// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1101// CHECK:       if.then:1102// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1103// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41104// CHECK-NEXT:    br label [[CLEANUP:%.*]]1105// CHECK:       if.else:1106// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1107// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41108// CHECK-NEXT:    br label [[CLEANUP]]1109// CHECK:       cleanup:1110// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]1111// CHECK-NEXT:    ret void1112//1113// CHECK-EH-03-LABEL: @_Z6test10b(1114// CHECK-EH-03-NEXT:  entry:1115// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41116// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11117// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11118// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41119// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41120// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41121// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41122// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81123// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11124// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1125// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11126// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11127// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1128// CHECK-EH-03:       if.then:1129// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1130// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1131// CHECK-EH-03:       invoke.cont:1132// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41133// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]1134// CHECK-EH-03:       lpad:1135// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1136// CHECK-EH-03-NEXT:            cleanup1137// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01138// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41139// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11140// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41141// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1142// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]]1143// CHECK-EH-03:       if.else:1144// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1145// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1146// CHECK-EH-03:       invoke.cont1:1147// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41148// CHECK-EH-03-NEXT:    br label [[CLEANUP]]1149// CHECK-EH-03:       cleanup:1150// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1151// CHECK-EH-03-NEXT:    ret void1152// CHECK-EH-03:       invoke.cont2:1153// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]1154// CHECK-EH-03:       eh.resume:1155// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41156// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41157// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01158// CHECK-EH-03-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11159// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL3]]1160// CHECK-EH-03:       terminate.lpad:1161// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }1162// CHECK-EH-03-NEXT:            catch ptr null1163// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 01164// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]]1165// CHECK-EH-03-NEXT:    unreachable1166//1167// CHECK-EH-11-LABEL: @_Z6test10b(1168// CHECK-EH-11-NEXT:  entry:1169// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41170// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11171// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11172// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41173// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41174// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41175// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41176// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81177// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11178// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1179// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11180// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11181// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1182// CHECK-EH-11:       if.then:1183// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1184// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1185// CHECK-EH-11:       invoke.cont:1186// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41187// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]1188// CHECK-EH-11:       lpad:1189// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1190// CHECK-EH-11-NEXT:            cleanup1191// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01192// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41193// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11194// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41195// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1196// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]1197// CHECK-EH-11:       if.else:1198// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1199// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1200// CHECK-EH-11:       invoke.cont1:1201// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41202// CHECK-EH-11-NEXT:    br label [[CLEANUP]]1203// CHECK-EH-11:       cleanup:1204// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1205// CHECK-EH-11-NEXT:    ret void1206// CHECK-EH-11:       eh.resume:1207// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41208// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41209// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01210// CHECK-EH-11-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11211// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]1212//1213X test10(bool b) { // http://wg21.link/p2025r2#ex-31214  X x;1215  if (b)1216    return x; // NRVO is impossible1217  else1218    return X();1219}1220 1221// CHECK-LABEL: @_Z6test11b(1222// CHECK-NEXT:  entry:1223// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41224// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11225// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11226// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41227// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41228// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81229// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11230// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1231// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11232// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11233// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1234// CHECK:       if.then:1235// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1236// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41237// CHECK-NEXT:    br label [[CLEANUP:%.*]]1238// CHECK:       if.end:1239// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1240// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41241// CHECK-NEXT:    br label [[CLEANUP]]1242// CHECK:       cleanup:1243// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]1244// CHECK-NEXT:    ret void1245//1246// CHECK-EH-03-LABEL: @_Z6test11b(1247// CHECK-EH-03-NEXT:  entry:1248// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41249// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11250// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11251// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41252// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41253// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41254// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41255// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81256// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11257// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1258// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11259// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11260// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1261// CHECK-EH-03:       if.then:1262// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1263// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1264// CHECK-EH-03:       invoke.cont:1265// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41266// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]1267// CHECK-EH-03:       lpad:1268// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1269// CHECK-EH-03-NEXT:            cleanup1270// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01271// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41272// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11273// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41274// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1275// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]]1276// CHECK-EH-03:       if.end:1277// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1278// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1279// CHECK-EH-03:       invoke.cont1:1280// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41281// CHECK-EH-03-NEXT:    br label [[CLEANUP]]1282// CHECK-EH-03:       cleanup:1283// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1284// CHECK-EH-03-NEXT:    ret void1285// CHECK-EH-03:       invoke.cont2:1286// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]1287// CHECK-EH-03:       eh.resume:1288// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41289// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41290// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01291// CHECK-EH-03-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11292// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL3]]1293// CHECK-EH-03:       terminate.lpad:1294// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }1295// CHECK-EH-03-NEXT:            catch ptr null1296// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 01297// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]]1298// CHECK-EH-03-NEXT:    unreachable1299//1300// CHECK-EH-11-LABEL: @_Z6test11b(1301// CHECK-EH-11-NEXT:  entry:1302// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41303// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11304// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11305// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41306// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41307// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41308// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41309// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81310// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11311// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1312// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11313// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11314// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1315// CHECK-EH-11:       if.then:1316// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1317// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1318// CHECK-EH-11:       invoke.cont:1319// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41320// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]1321// CHECK-EH-11:       lpad:1322// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1323// CHECK-EH-11-NEXT:            cleanup1324// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01325// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41326// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11327// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41328// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1329// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]1330// CHECK-EH-11:       if.end:1331// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1332// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1333// CHECK-EH-11:       invoke.cont1:1334// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41335// CHECK-EH-11-NEXT:    br label [[CLEANUP]]1336// CHECK-EH-11:       cleanup:1337// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1338// CHECK-EH-11-NEXT:    ret void1339// CHECK-EH-11:       eh.resume:1340// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41341// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41342// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01343// CHECK-EH-11-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11344// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]1345//1346X test11(bool b) { // http://wg21.link/p2025r2#ex-51347  X x;1348  if (b)1349    return X();1350  return x; // NRVO is impossible1351}1352 1353// CHECK-LABEL: @_Z6test12b(1354// CHECK-NEXT:  entry:1355// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41356// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11357// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 11358// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41359// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41360// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81361// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11362// CHECK-NEXT:    br label [[DO_BODY:%.*]]1363// CHECK:       do.body:1364// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 11365// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1366// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11367// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11368// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1369// CHECK:       if.then:1370// CHECK-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 41371// CHECK-NEXT:    br label [[CLEANUP:%.*]]1372// CHECK:       if.end:1373// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 11374// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41375// CHECK-NEXT:    br label [[CLEANUP]]1376// CHECK:       cleanup:1377// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11378// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1379// CHECK:       nrvo.unused:1380// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]1381// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]1382// CHECK:       nrvo.skipdtor:1383// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 41384// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [1385// CHECK-NEXT:      i32 2, label [[DO_END:%.*]]1386// CHECK-NEXT:      i32 1, label [[RETURN:%.*]]1387// CHECK-NEXT:    ]1388// CHECK:       do.end:1389// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1390// CHECK-NEXT:    br label [[RETURN]]1391// CHECK:       return:1392// CHECK-NEXT:    ret void1393// CHECK:       unreachable:1394// CHECK-NEXT:    unreachable1395//1396// CHECK-EH-03-LABEL: @_Z6test12b(1397// CHECK-EH-03-NEXT:  entry:1398// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41399// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11400// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 11401// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41402// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41403// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81404// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11405// CHECK-EH-03-NEXT:    br label [[DO_BODY:%.*]]1406// CHECK-EH-03:       do.body:1407// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 11408// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1409// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11410// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11411// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1412// CHECK-EH-03:       if.then:1413// CHECK-EH-03-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 41414// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]1415// CHECK-EH-03:       if.end:1416// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 11417// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41418// CHECK-EH-03-NEXT:    br label [[CLEANUP]]1419// CHECK-EH-03:       cleanup:1420// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11421// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1422// CHECK-EH-03:       nrvo.unused:1423// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1424// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]1425// CHECK-EH-03:       nrvo.skipdtor:1426// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 41427// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [1428// CHECK-EH-03-NEXT:      i32 2, label [[DO_END:%.*]]1429// CHECK-EH-03-NEXT:      i32 1, label [[RETURN:%.*]]1430// CHECK-EH-03-NEXT:    ]1431// CHECK-EH-03:       do.end:1432// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1433// CHECK-EH-03-NEXT:    br label [[RETURN]]1434// CHECK-EH-03:       return:1435// CHECK-EH-03-NEXT:    ret void1436// CHECK-EH-03:       unreachable:1437// CHECK-EH-03-NEXT:    unreachable1438//1439// CHECK-EH-11-LABEL: @_Z6test12b(1440// CHECK-EH-11-NEXT:  entry:1441// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41442// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11443// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 11444// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41445// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41446// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81447// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11448// CHECK-EH-11-NEXT:    br label [[DO_BODY:%.*]]1449// CHECK-EH-11:       do.body:1450// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 11451// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1452// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11453// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11454// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1455// CHECK-EH-11:       if.then:1456// CHECK-EH-11-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 41457// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]1458// CHECK-EH-11:       if.end:1459// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 11460// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41461// CHECK-EH-11-NEXT:    br label [[CLEANUP]]1462// CHECK-EH-11:       cleanup:1463// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11464// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1465// CHECK-EH-11:       nrvo.unused:1466// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1467// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]1468// CHECK-EH-11:       nrvo.skipdtor:1469// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 41470// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [1471// CHECK-EH-11-NEXT:      i32 2, label [[DO_END:%.*]]1472// CHECK-EH-11-NEXT:      i32 1, label [[RETURN:%.*]]1473// CHECK-EH-11-NEXT:    ]1474// CHECK-EH-11:       do.end:1475// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1476// CHECK-EH-11-NEXT:    br label [[RETURN]]1477// CHECK-EH-11:       return:1478// CHECK-EH-11-NEXT:    ret void1479// CHECK-EH-11:       unreachable:1480// CHECK-EH-11-NEXT:    unreachable1481//1482X test12(bool b) { // http://wg21.link/p2025r2#ex-61483  do {1484    X x;1485    if (b)1486      break;1487    return x; // NRVO happens1488  } while (false);1489  return X();1490}1491 1492// CHECK-LABEL: @_Z6test13b(1493// CHECK-NEXT:  entry:1494// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41495// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11496// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 11497// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41498// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81499// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11500// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11501// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11502// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1503// CHECK:       if.then:1504// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1505// CHECK-NEXT:    br label [[RETURN:%.*]]1506// CHECK:       if.end:1507// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 11508// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1509// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 11510// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11511// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1512// CHECK:       nrvo.unused:1513// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]1514// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]1515// CHECK:       nrvo.skipdtor:1516// CHECK-NEXT:    br label [[RETURN]]1517// CHECK:       return:1518// CHECK-NEXT:    ret void1519//1520// CHECK-EH-03-LABEL: @_Z6test13b(1521// CHECK-EH-03-NEXT:  entry:1522// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41523// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11524// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 11525// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41526// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81527// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11528// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11529// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11530// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1531// CHECK-EH-03:       if.then:1532// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1533// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]1534// CHECK-EH-03:       if.end:1535// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 11536// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1537// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 11538// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11539// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1540// CHECK-EH-03:       nrvo.unused:1541// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1542// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]1543// CHECK-EH-03:       nrvo.skipdtor:1544// CHECK-EH-03-NEXT:    br label [[RETURN]]1545// CHECK-EH-03:       return:1546// CHECK-EH-03-NEXT:    ret void1547//1548// CHECK-EH-11-LABEL: @_Z6test13b(1549// CHECK-EH-11-NEXT:  entry:1550// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41551// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11552// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 11553// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41554// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81555// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11556// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11557// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11558// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1559// CHECK-EH-11:       if.then:1560// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1561// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]1562// CHECK-EH-11:       if.end:1563// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 11564// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1565// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 11566// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11567// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1568// CHECK-EH-11:       nrvo.unused:1569// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1570// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]1571// CHECK-EH-11:       nrvo.skipdtor:1572// CHECK-EH-11-NEXT:    br label [[RETURN]]1573// CHECK-EH-11:       return:1574// CHECK-EH-11-NEXT:    ret void1575//1576X test13(bool b) { // http://wg21.link/p2025r2#ex-71577  if (b)1578    return X();1579  X x;1580  return x; // FIXME: NRVO could happen, but doesn't1581}1582 1583// CHECK-LABEL: @_Z6test14b(1584// CHECK-NEXT:  entry:1585// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41586// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11587// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11588// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41589// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 11590// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41591// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81592// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11593// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1594// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11595// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11596// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1597// CHECK:       if.then:1598// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1599// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41600// CHECK-NEXT:    br label [[CLEANUP:%.*]]1601// CHECK:       if.end:1602// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 11603// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1604// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 11605// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41606// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11607// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1608// CHECK:       nrvo.unused:1609// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]1610// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]1611// CHECK:       nrvo.skipdtor:1612// CHECK-NEXT:    br label [[CLEANUP]]1613// CHECK:       cleanup:1614// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]1615// CHECK-NEXT:    ret void1616//1617// CHECK-EH-03-LABEL: @_Z6test14b(1618// CHECK-EH-03-NEXT:  entry:1619// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41620// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11621// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11622// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41623// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41624// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41625// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 11626// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41627// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81628// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11629// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1630// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11631// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11632// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1633// CHECK-EH-03:       if.then:1634// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1635// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1636// CHECK-EH-03:       invoke.cont:1637// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41638// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]1639// CHECK-EH-03:       lpad:1640// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1641// CHECK-EH-03-NEXT:            cleanup1642// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01643// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41644// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11645// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41646// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1647// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[TERMINATE_LPAD:%.*]]1648// CHECK-EH-03:       if.end:1649// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 11650// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1651// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1652// CHECK-EH-03:       invoke.cont1:1653// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 11654// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41655// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11656// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1657// CHECK-EH-03:       nrvo.unused:1658// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1659// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]1660// CHECK-EH-03:       invoke.cont2:1661// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]1662// CHECK-EH-03:       nrvo.skipdtor:1663// CHECK-EH-03-NEXT:    br label [[CLEANUP]]1664// CHECK-EH-03:       cleanup:1665// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1666// CHECK-EH-03-NEXT:    ret void1667// CHECK-EH-03:       invoke.cont3:1668// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]1669// CHECK-EH-03:       eh.resume:1670// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41671// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41672// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01673// CHECK-EH-03-NEXT:    [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11674// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL4]]1675// CHECK-EH-03:       terminate.lpad:1676// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }1677// CHECK-EH-03-NEXT:            catch ptr null1678// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 01679// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]]1680// CHECK-EH-03-NEXT:    unreachable1681//1682// CHECK-EH-11-LABEL: @_Z6test14b(1683// CHECK-EH-11-NEXT:  entry:1684// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41685// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11686// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11687// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41688// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41689// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41690// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 11691// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41692// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81693// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11694// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1695// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11696// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11697// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1698// CHECK-EH-11:       if.then:1699// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1700// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1701// CHECK-EH-11:       invoke.cont:1702// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41703// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]1704// CHECK-EH-11:       lpad:1705// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1706// CHECK-EH-11-NEXT:            cleanup1707// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01708// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41709// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11710// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41711// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1712// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]1713// CHECK-EH-11:       if.end:1714// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 11715// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1716// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1717// CHECK-EH-11:       invoke.cont1:1718// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 11719// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41720// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11721// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1722// CHECK-EH-11:       nrvo.unused:1723// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1724// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]1725// CHECK-EH-11:       nrvo.skipdtor:1726// CHECK-EH-11-NEXT:    br label [[CLEANUP]]1727// CHECK-EH-11:       cleanup:1728// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1729// CHECK-EH-11-NEXT:    ret void1730// CHECK-EH-11:       eh.resume:1731// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41732// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41733// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01734// CHECK-EH-11-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11735// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]1736//1737X test14(bool b) { // http://wg21.link/p2025r2#ex-81738  X x;1739  if (b)1740    return x;1741  X y;1742  return y; // FIXME: NRVO could happen, but doesn't1743}1744 1745// CHECK-LABEL: @_Z6test15b(1746// CHECK-NEXT:  entry:1747// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41748// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11749// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11750// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41751// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 11752// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41753// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81754// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11755// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1756// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11757// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11758// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1759// CHECK:       if.then:1760// CHECK-NEXT:    call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1761// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41762// CHECK-NEXT:    br label [[CLEANUP:%.*]]1763// CHECK:       if.end:1764// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 11765// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1766// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 11767// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41768// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11769// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1770// CHECK:       nrvo.unused:1771// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]1772// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]1773// CHECK:       nrvo.skipdtor:1774// CHECK-NEXT:    br label [[CLEANUP]]1775// CHECK:       cleanup:1776// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]1777// CHECK-NEXT:    ret void1778//1779// CHECK-EH-03-LABEL: @_Z6test15b(1780// CHECK-EH-03-NEXT:  entry:1781// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41782// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11783// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11784// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41785// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41786// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41787// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 11788// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41789// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81790// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11791// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1792// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11793// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11794// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1795// CHECK-EH-03:       if.then:1796// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1797// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1798// CHECK-EH-03:       invoke.cont:1799// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41800// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]1801// CHECK-EH-03:       lpad:1802// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1803// CHECK-EH-03-NEXT:            cleanup1804// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01805// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41806// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11807// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41808// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1809// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[TERMINATE_LPAD:%.*]]1810// CHECK-EH-03:       if.end:1811// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 11812// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1813// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1814// CHECK-EH-03:       invoke.cont1:1815// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 11816// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41817// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11818// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1819// CHECK-EH-03:       nrvo.unused:1820// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1821// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]1822// CHECK-EH-03:       invoke.cont2:1823// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]1824// CHECK-EH-03:       nrvo.skipdtor:1825// CHECK-EH-03-NEXT:    br label [[CLEANUP]]1826// CHECK-EH-03:       cleanup:1827// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1828// CHECK-EH-03-NEXT:    ret void1829// CHECK-EH-03:       invoke.cont3:1830// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]1831// CHECK-EH-03:       eh.resume:1832// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41833// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41834// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01835// CHECK-EH-03-NEXT:    [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11836// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL4]]1837// CHECK-EH-03:       terminate.lpad:1838// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }1839// CHECK-EH-03-NEXT:            catch ptr null1840// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 01841// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]]1842// CHECK-EH-03-NEXT:    unreachable1843//1844// CHECK-EH-11-LABEL: @_Z6test15b(1845// CHECK-EH-11-NEXT:  entry:1846// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41847// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 11848// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11849// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41850// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41851// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41852// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 11853// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41854// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i81855// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 11856// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1857// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 11858// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i11859// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]1860// CHECK-EH-11:       if.then:1861// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])1862// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1863// CHECK-EH-11:       invoke.cont:1864// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41865// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]1866// CHECK-EH-11:       lpad:1867// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1868// CHECK-EH-11-NEXT:            cleanup1869// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01870// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41871// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11872// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41873// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1874// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]1875// CHECK-EH-11:       if.end:1876// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 11877// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1878// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]]1879// CHECK-EH-11:       invoke.cont1:1880// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 11881// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41882// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 11883// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]1884// CHECK-EH-11:       nrvo.unused:1885// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]1886// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]1887// CHECK-EH-11:       nrvo.skipdtor:1888// CHECK-EH-11-NEXT:    br label [[CLEANUP]]1889// CHECK-EH-11:       cleanup:1890// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1891// CHECK-EH-11-NEXT:    ret void1892// CHECK-EH-11:       eh.resume:1893// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41894// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41895// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01896// CHECK-EH-11-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11897// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]1898//1899X test15(bool b) { // http://wg21.link/p2025r2#ex-151900  X x;1901  if (b)1902    return (x);1903  X y;1904  return ((y)); // FIXME: NRVO could happen, but doesn't1905}1906 1907#ifdef CXX111908// CHECK-EH-11-LABEL: @_Z6test16v(1909// CHECK-EH-11-NEXT:  entry:1910// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 11911// CHECK-EH-11-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_X]], align 11912// CHECK-EH-11-NEXT:    [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 41913// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 41914// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 41915// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])1916// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[CLASS_ANON]], ptr [[REF_TMP]], i32 0, i32 01917// CHECK-EH-11-NEXT:    store ptr [[X]], ptr [[TMP0]], align 41918// CHECK-EH-11-NEXT:    invoke void @"_ZZ6test16vENK3$_0clEv"(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]])1919// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]1920// CHECK-EH-11:       invoke.cont:1921// CHECK-EH-11-NEXT:    invoke void @_Z8ConsumeX1X(ptr noundef [[AGG_TMP]])1922// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]1923// CHECK-EH-11:       invoke.cont2:1924// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR6]]1925// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1926// CHECK-EH-11-NEXT:    ret void1927// CHECK-EH-11:       lpad:1928// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }1929// CHECK-EH-11-NEXT:            cleanup1930// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 01931// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 41932// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 11933// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 41934// CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]1935// CHECK-EH-11:       lpad1:1936// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }1937// CHECK-EH-11-NEXT:            cleanup1938// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 01939// CHECK-EH-11-NEXT:    store ptr [[TMP5]], ptr [[EXN_SLOT]], align 41940// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 11941// CHECK-EH-11-NEXT:    store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 41942// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR6]]1943// CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]1944// CHECK-EH-11:       ehcleanup:1945// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]1946// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]1947// CHECK-EH-11:       eh.resume:1948// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 41949// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 41950// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 01951// CHECK-EH-11-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 11952// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL3]]1953//1954void test16() { // http://wg21.link/p2025r2#ex-91955  X x;1956  ConsumeX([&] {1957    X y(x);1958    return y; // NRVO happens1959  }());1960}1961#endif1962 1963// CHECK-LABEL: @_Z6test17i(1964// CHECK-NEXT:  entry:1965// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 41966// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 41967// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 11968// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 41969// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 41970// CHECK-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 41971// CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]1972// CHECK:       if.then:1973// CHECK-NEXT:    br label [[IMPOSSIBLE:%.*]]1974// CHECK:       impossible:1975// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 41976// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 31977// CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]1978// CHECK:       if.then1:1979// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1980// CHECK-NEXT:    br label [[RETURN:%.*]]1981// CHECK:       if.end:1982// CHECK-NEXT:    br label [[IF_END2]]1983// CHECK:       if.end2:1984// CHECK-NEXT:    br label [[WHILE_BODY:%.*]]1985// CHECK:       while.body:1986// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 11987// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])1988// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 41989// CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 01990// CHECK-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]1991// CHECK:       if.then4:1992// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 11993// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 41994// CHECK-NEXT:    br label [[CLEANUP:%.*]]1995// CHECK:       if.end5:1996// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 41997// CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 11998// CHECK-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]1999// CHECK:       if.then7:2000// CHECK-NEXT:    store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 42001// CHECK-NEXT:    br label [[CLEANUP]]2002// CHECK:       if.end8:2003// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 42004// CHECK-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 22005// CHECK-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]2006// CHECK:       if.then10:2007// CHECK-NEXT:    store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 42008// CHECK-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP3:![0-9]+]]2009// CHECK:       if.end11:2010// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 42011// CHECK-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 32012// CHECK-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]2013// CHECK:       if.then13:2014// CHECK-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 42015// CHECK-NEXT:    br label [[CLEANUP]]2016// CHECK:       if.end14:2017// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 42018// CHECK-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 42019// CHECK-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]2020// CHECK:       if.then16:2021// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR4]]2022// CHECK-NEXT:    br label [[IF_END17]]2023// CHECK:       if.end17:2024// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 42025// CHECK-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 52026// CHECK-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]2027// CHECK:       if.then19:2028// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 12029// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42030// CHECK-NEXT:    br label [[CLEANUP]]2031// CHECK:       if.end20:2032// CHECK-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42033// CHECK-NEXT:    br label [[CLEANUP]]2034// CHECK:       cleanup:2035// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12036// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2037// CHECK:       nrvo.unused:2038// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2039// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]2040// CHECK:       nrvo.skipdtor:2041// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42042// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2043// CHECK-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2044// CHECK-NEXT:      i32 1, label [[RETURN]]2045// CHECK-NEXT:      i32 4, label [[WHILE_END:%.*]]2046// CHECK-NEXT:      i32 3, label [[WHILE_BODY]]2047// CHECK-NEXT:      i32 2, label [[IMPOSSIBLE]]2048// CHECK-NEXT:    ]2049// CHECK:       cleanup.cont:2050// CHECK-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP3]]2051// CHECK:       while.end:2052// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2053// CHECK-NEXT:    br label [[RETURN]]2054// CHECK:       return:2055// CHECK-NEXT:    ret void2056// CHECK:       unreachable:2057// CHECK-NEXT:    unreachable2058//2059// CHECK-EH-03-LABEL: @_Z6test17i(2060// CHECK-EH-03-NEXT:  entry:2061// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42062// CHECK-EH-03-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 42063// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 12064// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 42065// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42066// CHECK-EH-03-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 42067// CHECK-EH-03-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]2068// CHECK-EH-03:       if.then:2069// CHECK-EH-03-NEXT:    br label [[IMPOSSIBLE:%.*]]2070// CHECK-EH-03:       impossible:2071// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 42072// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 32073// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]2074// CHECK-EH-03:       if.then1:2075// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2076// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]2077// CHECK-EH-03:       if.end:2078// CHECK-EH-03-NEXT:    br label [[IF_END2]]2079// CHECK-EH-03:       if.end2:2080// CHECK-EH-03-NEXT:    br label [[WHILE_BODY:%.*]]2081// CHECK-EH-03:       while.body:2082// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 12083// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2084// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 42085// CHECK-EH-03-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 02086// CHECK-EH-03-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]2087// CHECK-EH-03:       if.then4:2088// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12089// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42090// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]2091// CHECK-EH-03:       if.end5:2092// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 42093// CHECK-EH-03-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 12094// CHECK-EH-03-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]2095// CHECK-EH-03:       if.then7:2096// CHECK-EH-03-NEXT:    store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 42097// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2098// CHECK-EH-03:       if.end8:2099// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 42100// CHECK-EH-03-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 22101// CHECK-EH-03-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]2102// CHECK-EH-03:       if.then10:2103// CHECK-EH-03-NEXT:    store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 42104// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2105// CHECK-EH-03:       if.end11:2106// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 42107// CHECK-EH-03-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 32108// CHECK-EH-03-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]2109// CHECK-EH-03:       if.then13:2110// CHECK-EH-03-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 42111// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2112// CHECK-EH-03:       if.end14:2113// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 42114// CHECK-EH-03-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 42115// CHECK-EH-03-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]2116// CHECK-EH-03:       if.then16:2117// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]2118// CHECK-EH-03-NEXT:    br label [[IF_END17]]2119// CHECK-EH-03:       if.end17:2120// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 42121// CHECK-EH-03-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 52122// CHECK-EH-03-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]2123// CHECK-EH-03:       if.then19:2124// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12125// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42126// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2127// CHECK-EH-03:       if.end20:2128// CHECK-EH-03-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42129// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2130// CHECK-EH-03:       cleanup:2131// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12132// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2133// CHECK-EH-03:       nrvo.unused:2134// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2135// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]2136// CHECK-EH-03:       nrvo.skipdtor:2137// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42138// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2139// CHECK-EH-03-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2140// CHECK-EH-03-NEXT:      i32 1, label [[RETURN]]2141// CHECK-EH-03-NEXT:      i32 4, label [[WHILE_END:%.*]]2142// CHECK-EH-03-NEXT:      i32 3, label [[WHILE_BODY]]2143// CHECK-EH-03-NEXT:      i32 2, label [[IMPOSSIBLE]]2144// CHECK-EH-03-NEXT:    ]2145// CHECK-EH-03:       cleanup.cont:2146// CHECK-EH-03-NEXT:    br label [[WHILE_BODY]]2147// CHECK-EH-03:       while.end:2148// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2149// CHECK-EH-03-NEXT:    br label [[RETURN]]2150// CHECK-EH-03:       return:2151// CHECK-EH-03-NEXT:    ret void2152// CHECK-EH-03:       unreachable:2153// CHECK-EH-03-NEXT:    unreachable2154//2155// CHECK-EH-11-LABEL: @_Z6test17i(2156// CHECK-EH-11-NEXT:  entry:2157// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42158// CHECK-EH-11-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 42159// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12160// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 42161// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42162// CHECK-EH-11-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 42163// CHECK-EH-11-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]]2164// CHECK-EH-11:       if.then:2165// CHECK-EH-11-NEXT:    br label [[IMPOSSIBLE:%.*]]2166// CHECK-EH-11:       impossible:2167// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 42168// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 32169// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]2170// CHECK-EH-11:       if.then1:2171// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2172// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]2173// CHECK-EH-11:       if.end:2174// CHECK-EH-11-NEXT:    br label [[IF_END2]]2175// CHECK-EH-11:       if.end2:2176// CHECK-EH-11-NEXT:    br label [[WHILE_BODY:%.*]]2177// CHECK-EH-11:       while.body:2178// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12179// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2180// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 42181// CHECK-EH-11-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 02182// CHECK-EH-11-NEXT:    br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]2183// CHECK-EH-11:       if.then4:2184// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12185// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42186// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]2187// CHECK-EH-11:       if.end5:2188// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 42189// CHECK-EH-11-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 12190// CHECK-EH-11-NEXT:    br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]]2191// CHECK-EH-11:       if.then7:2192// CHECK-EH-11-NEXT:    store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 42193// CHECK-EH-11-NEXT:    br label [[CLEANUP]]2194// CHECK-EH-11:       if.end8:2195// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 42196// CHECK-EH-11-NEXT:    [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 22197// CHECK-EH-11-NEXT:    br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]]2198// CHECK-EH-11:       if.then10:2199// CHECK-EH-11-NEXT:    store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 42200// CHECK-EH-11-NEXT:    br label [[CLEANUP]], !llvm.loop [[LOOP4:![0-9]+]]2201// CHECK-EH-11:       if.end11:2202// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 42203// CHECK-EH-11-NEXT:    [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 32204// CHECK-EH-11-NEXT:    br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]]2205// CHECK-EH-11:       if.then13:2206// CHECK-EH-11-NEXT:    store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 42207// CHECK-EH-11-NEXT:    br label [[CLEANUP]]2208// CHECK-EH-11:       if.end14:2209// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 42210// CHECK-EH-11-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 42211// CHECK-EH-11-NEXT:    br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]]2212// CHECK-EH-11:       if.then16:2213// CHECK-EH-11-NEXT:    call void @exit(i32 noundef 1) #[[ATTR6]]2214// CHECK-EH-11-NEXT:    br label [[IF_END17]]2215// CHECK-EH-11:       if.end17:2216// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 42217// CHECK-EH-11-NEXT:    [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 52218// CHECK-EH-11-NEXT:    br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]]2219// CHECK-EH-11:       if.then19:2220// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12221// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42222// CHECK-EH-11-NEXT:    br label [[CLEANUP]]2223// CHECK-EH-11:       if.end20:2224// CHECK-EH-11-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42225// CHECK-EH-11-NEXT:    br label [[CLEANUP]]2226// CHECK-EH-11:       cleanup:2227// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12228// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2229// CHECK-EH-11:       nrvo.unused:2230// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2231// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2232// CHECK-EH-11:       nrvo.skipdtor:2233// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42234// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2235// CHECK-EH-11-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2236// CHECK-EH-11-NEXT:      i32 1, label [[RETURN]]2237// CHECK-EH-11-NEXT:      i32 4, label [[WHILE_END:%.*]]2238// CHECK-EH-11-NEXT:      i32 3, label [[WHILE_BODY]]2239// CHECK-EH-11-NEXT:      i32 2, label [[IMPOSSIBLE]]2240// CHECK-EH-11-NEXT:    ]2241// CHECK-EH-11:       cleanup.cont:2242// CHECK-EH-11-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP4]]2243// CHECK-EH-11:       while.end:2244// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2245// CHECK-EH-11-NEXT:    br label [[RETURN]]2246// CHECK-EH-11:       return:2247// CHECK-EH-11-NEXT:    ret void2248// CHECK-EH-11:       unreachable:2249// CHECK-EH-11-NEXT:    unreachable2250//2251X test17(int i) { // http://wg21.link/p2025r2#ex-102252  if (false) {2253  impossible:2254    if (i == 3)2255      return X();2256  }2257 2258  while (true) {2259    X x;2260    if (i == 0)2261      return x; // NRVO happens2262    if (i == 1)2263      break;2264    if (i == 2)2265      continue;2266    if (i == 3)2267      goto impossible;2268    if (i == 4)2269      exit(1);2270    if (i == 5)2271      return x; // NRVO happens2272  }2273  return X();2274}2275 2276// CHECK-LABEL: @_Z6test18i(2277// CHECK-NEXT:  entry:2278// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42279// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 42280// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 12281// CHECK-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 42282// CHECK-NEXT:    [[NRVO1:%.*]] = alloca i1, align 12283// CHECK-NEXT:    [[NRVO11:%.*]] = alloca i1, align 12284// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42285// CHECK-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 42286// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 12287// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2288// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 42289// CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 02290// CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2291// CHECK:       if.then:2292// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 12293// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42294// CHECK-NEXT:    br label [[CLEANUP:%.*]]2295// CHECK:       if.end:2296// CHECK-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42297// CHECK-NEXT:    br label [[CLEANUP]]2298// CHECK:       cleanup:2299// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12300// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2301// CHECK:       nrvo.unused:2302// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2303// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]2304// CHECK:       nrvo.skipdtor:2305// CHECK-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42306// CHECK-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2307// CHECK-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2308// CHECK-NEXT:      i32 1, label [[RETURN:%.*]]2309// CHECK-NEXT:    ]2310// CHECK:       cleanup.cont:2311// CHECK-NEXT:    store i1 false, ptr [[NRVO1]], align 12312// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2313// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 42314// CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 12315// CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]]2316// CHECK:       if.then3:2317// CHECK-NEXT:    store i1 true, ptr [[NRVO1]], align 12318// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42319// CHECK-NEXT:    br label [[CLEANUP5:%.*]]2320// CHECK:       if.end4:2321// CHECK-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42322// CHECK-NEXT:    br label [[CLEANUP5]]2323// CHECK:       cleanup5:2324// CHECK-NEXT:    [[NRVO_VAL6:%.*]] = load i1, ptr [[NRVO1]], align 12325// CHECK-NEXT:    br i1 [[NRVO_VAL6]], label [[NRVO_SKIPDTOR8:%.*]], label [[NRVO_UNUSED7:%.*]]2326// CHECK:       nrvo.unused7:2327// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2328// CHECK-NEXT:    br label [[NRVO_SKIPDTOR8]]2329// CHECK:       nrvo.skipdtor8:2330// CHECK-NEXT:    [[CLEANUP_DEST9:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42331// CHECK-NEXT:    switch i32 [[CLEANUP_DEST9]], label [[UNREACHABLE]] [2332// CHECK-NEXT:      i32 0, label [[CLEANUP_CONT10:%.*]]2333// CHECK-NEXT:      i32 1, label [[RETURN]]2334// CHECK-NEXT:    ]2335// CHECK:       cleanup.cont10:2336// CHECK-NEXT:    store i1 false, ptr [[NRVO11]], align 12337// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2338// CHECK-NEXT:    store i1 true, ptr [[NRVO11]], align 12339// CHECK-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42340// CHECK-NEXT:    [[NRVO_VAL13:%.*]] = load i1, ptr [[NRVO11]], align 12341// CHECK-NEXT:    br i1 [[NRVO_VAL13]], label [[NRVO_SKIPDTOR15:%.*]], label [[NRVO_UNUSED14:%.*]]2342// CHECK:       nrvo.unused14:2343// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2344// CHECK-NEXT:    br label [[NRVO_SKIPDTOR15]]2345// CHECK:       nrvo.skipdtor15:2346// CHECK-NEXT:    br label [[RETURN]]2347// CHECK:       return:2348// CHECK-NEXT:    ret void2349// CHECK:       unreachable:2350// CHECK-NEXT:    unreachable2351//2352// CHECK-EH-03-LABEL: @_Z6test18i(2353// CHECK-EH-03-NEXT:  entry:2354// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42355// CHECK-EH-03-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 42356// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 12357// CHECK-EH-03-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 42358// CHECK-EH-03-NEXT:    [[NRVO1:%.*]] = alloca i1, align 12359// CHECK-EH-03-NEXT:    [[NRVO11:%.*]] = alloca i1, align 12360// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42361// CHECK-EH-03-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 42362// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 12363// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2364// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 42365// CHECK-EH-03-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 02366// CHECK-EH-03-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2367// CHECK-EH-03:       if.then:2368// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12369// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42370// CHECK-EH-03-NEXT:    br label [[CLEANUP:%.*]]2371// CHECK-EH-03:       if.end:2372// CHECK-EH-03-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42373// CHECK-EH-03-NEXT:    br label [[CLEANUP]]2374// CHECK-EH-03:       cleanup:2375// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12376// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2377// CHECK-EH-03:       nrvo.unused:2378// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2379// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]2380// CHECK-EH-03:       nrvo.skipdtor:2381// CHECK-EH-03-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42382// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2383// CHECK-EH-03-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2384// CHECK-EH-03-NEXT:      i32 1, label [[RETURN:%.*]]2385// CHECK-EH-03-NEXT:    ]2386// CHECK-EH-03:       cleanup.cont:2387// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO1]], align 12388// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2389// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 42390// CHECK-EH-03-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 12391// CHECK-EH-03-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]]2392// CHECK-EH-03:       if.then3:2393// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO1]], align 12394// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42395// CHECK-EH-03-NEXT:    br label [[CLEANUP5:%.*]]2396// CHECK-EH-03:       if.end4:2397// CHECK-EH-03-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42398// CHECK-EH-03-NEXT:    br label [[CLEANUP5]]2399// CHECK-EH-03:       cleanup5:2400// CHECK-EH-03-NEXT:    [[NRVO_VAL6:%.*]] = load i1, ptr [[NRVO1]], align 12401// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL6]], label [[NRVO_SKIPDTOR8:%.*]], label [[NRVO_UNUSED7:%.*]]2402// CHECK-EH-03:       nrvo.unused7:2403// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2404// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR8]]2405// CHECK-EH-03:       nrvo.skipdtor8:2406// CHECK-EH-03-NEXT:    [[CLEANUP_DEST9:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42407// CHECK-EH-03-NEXT:    switch i32 [[CLEANUP_DEST9]], label [[UNREACHABLE]] [2408// CHECK-EH-03-NEXT:      i32 0, label [[CLEANUP_CONT10:%.*]]2409// CHECK-EH-03-NEXT:      i32 1, label [[RETURN]]2410// CHECK-EH-03-NEXT:    ]2411// CHECK-EH-03:       cleanup.cont10:2412// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO11]], align 12413// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2414// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO11]], align 12415// CHECK-EH-03-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42416// CHECK-EH-03-NEXT:    [[NRVO_VAL13:%.*]] = load i1, ptr [[NRVO11]], align 12417// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL13]], label [[NRVO_SKIPDTOR15:%.*]], label [[NRVO_UNUSED14:%.*]]2418// CHECK-EH-03:       nrvo.unused14:2419// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2420// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR15]]2421// CHECK-EH-03:       nrvo.skipdtor15:2422// CHECK-EH-03-NEXT:    br label [[RETURN]]2423// CHECK-EH-03:       return:2424// CHECK-EH-03-NEXT:    ret void2425// CHECK-EH-03:       unreachable:2426// CHECK-EH-03-NEXT:    unreachable2427//2428// CHECK-EH-11-LABEL: @_Z6test18i(2429// CHECK-EH-11-NEXT:  entry:2430// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42431// CHECK-EH-11-NEXT:    [[I_ADDR:%.*]] = alloca i32, align 42432// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12433// CHECK-EH-11-NEXT:    [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 42434// CHECK-EH-11-NEXT:    [[NRVO1:%.*]] = alloca i1, align 12435// CHECK-EH-11-NEXT:    [[NRVO11:%.*]] = alloca i1, align 12436// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42437// CHECK-EH-11-NEXT:    store i32 [[I:%.*]], ptr [[I_ADDR]], align 42438// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12439// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2440// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 42441// CHECK-EH-11-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 02442// CHECK-EH-11-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2443// CHECK-EH-11:       if.then:2444// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12445// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42446// CHECK-EH-11-NEXT:    br label [[CLEANUP:%.*]]2447// CHECK-EH-11:       if.end:2448// CHECK-EH-11-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42449// CHECK-EH-11-NEXT:    br label [[CLEANUP]]2450// CHECK-EH-11:       cleanup:2451// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12452// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2453// CHECK-EH-11:       nrvo.unused:2454// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2455// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2456// CHECK-EH-11:       nrvo.skipdtor:2457// CHECK-EH-11-NEXT:    [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42458// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [2459// CHECK-EH-11-NEXT:      i32 0, label [[CLEANUP_CONT:%.*]]2460// CHECK-EH-11-NEXT:      i32 1, label [[RETURN:%.*]]2461// CHECK-EH-11-NEXT:    ]2462// CHECK-EH-11:       cleanup.cont:2463// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO1]], align 12464// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2465// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 42466// CHECK-EH-11-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 12467// CHECK-EH-11-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]]2468// CHECK-EH-11:       if.then3:2469// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO1]], align 12470// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42471// CHECK-EH-11-NEXT:    br label [[CLEANUP5:%.*]]2472// CHECK-EH-11:       if.end4:2473// CHECK-EH-11-NEXT:    store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 42474// CHECK-EH-11-NEXT:    br label [[CLEANUP5]]2475// CHECK-EH-11:       cleanup5:2476// CHECK-EH-11-NEXT:    [[NRVO_VAL6:%.*]] = load i1, ptr [[NRVO1]], align 12477// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL6]], label [[NRVO_SKIPDTOR8:%.*]], label [[NRVO_UNUSED7:%.*]]2478// CHECK-EH-11:       nrvo.unused7:2479// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2480// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR8]]2481// CHECK-EH-11:       nrvo.skipdtor8:2482// CHECK-EH-11-NEXT:    [[CLEANUP_DEST9:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 42483// CHECK-EH-11-NEXT:    switch i32 [[CLEANUP_DEST9]], label [[UNREACHABLE]] [2484// CHECK-EH-11-NEXT:      i32 0, label [[CLEANUP_CONT10:%.*]]2485// CHECK-EH-11-NEXT:      i32 1, label [[RETURN]]2486// CHECK-EH-11-NEXT:    ]2487// CHECK-EH-11:       cleanup.cont10:2488// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO11]], align 12489// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2490// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO11]], align 12491// CHECK-EH-11-NEXT:    store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 42492// CHECK-EH-11-NEXT:    [[NRVO_VAL13:%.*]] = load i1, ptr [[NRVO11]], align 12493// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL13]], label [[NRVO_SKIPDTOR15:%.*]], label [[NRVO_UNUSED14:%.*]]2494// CHECK-EH-11:       nrvo.unused14:2495// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2496// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR15]]2497// CHECK-EH-11:       nrvo.skipdtor15:2498// CHECK-EH-11-NEXT:    br label [[RETURN]]2499// CHECK-EH-11:       return:2500// CHECK-EH-11-NEXT:    ret void2501// CHECK-EH-11:       unreachable:2502// CHECK-EH-11-NEXT:    unreachable2503//2504X test18(int i) { // http://wg21.link/p2025r2#ex-112505  {2506    {2507      X x;2508      if (i == 0)2509        return x; // NRVO happens2510    }2511    X y;2512    if (i == 1)2513      return y; // FIXME: NRVO could happen, but doesn't2514  }2515  X z;2516  return z; // FIXME: NRVO could happen, but doesn't2517}2518 2519#ifdef CXX112520// CHECK-EH-11-LABEL: @_Z6test19v(2521// CHECK-EH-11-NEXT:  entry:2522// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42523// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12524// CHECK-EH-11-NEXT:    [[L:%.*]] = alloca [[CLASS_X:%.*]], align 12525// CHECK-EH-11-NEXT:    [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 42526// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 42527// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 42528// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42529// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12530// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2531// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[CLASS_ANON_0]], ptr [[REF_TMP]], i32 0, i32 02532// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT]], ptr [[TMP0]], align 42533// CHECK-EH-11-NEXT:    invoke void @"_ZZ6test19vENK3$_0clEv"(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[L]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]])2534// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]2535// CHECK-EH-11:       invoke.cont:2536// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12537// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[L]]) #[[ATTR6]]2538// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12539// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2540// CHECK-EH-11:       lpad:2541// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }2542// CHECK-EH-11-NEXT:            cleanup2543// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 02544// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 42545// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 12546// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 42547// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2548// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]2549// CHECK-EH-11:       nrvo.unused:2550// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2551// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2552// CHECK-EH-11:       nrvo.skipdtor:2553// CHECK-EH-11-NEXT:    ret void2554// CHECK-EH-11:       eh.resume:2555// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 42556// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 42557// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 02558// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 12559// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL1]]2560//2561X test19() { // http://wg21.link/p2025r2#ex-122562  X x;2563  struct S {2564    X f() { return X(); }2565  };2566  auto L = [&x]() { return X(); }();2567  if constexpr (false) {2568    return X();2569  }2570  return x; // NRVO happens2571}2572 2573template <bool B>2574X test20() { // http://wg21.link/p2025r2#ex-182575  X x;2576  if constexpr (B) {2577    if (false)2578      return X();2579  }2580  return x; // FIXME: NRVO could happen when B == false, but doesn't2581}2582 2583// CHECK-EH-11-LABEL: @_Z17test20instantiatev(2584// CHECK-EH-11-NEXT:  entry:2585// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 12586// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 12587// CHECK-EH-11-NEXT:    call void @_Z6test20ILb1EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]])2588// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]]2589// CHECK-EH-11-NEXT:    call void @_Z6test20ILb0EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]])2590// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]]2591// CHECK-EH-11-NEXT:    ret void2592//2593void test20instantiate() {2594  test20<true>();2595  test20<false>();2596}2597#endif2598 2599// CHECK-LABEL: @_Z6test21v(2600// CHECK-NEXT:  entry:2601// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42602// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 12603// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42604// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 12605// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2606// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 12607// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12608// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2609// CHECK:       nrvo.unused:2610// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2611// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]2612// CHECK:       nrvo.skipdtor:2613// CHECK-NEXT:    ret void2614//2615// CHECK-EH-03-LABEL: @_Z6test21v(2616// CHECK-EH-03-NEXT:  entry:2617// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42618// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 12619// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42620// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 12621// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2622// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12623// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12624// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2625// CHECK-EH-03:       nrvo.unused:2626// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2627// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]2628// CHECK-EH-03:       nrvo.skipdtor:2629// CHECK-EH-03-NEXT:    ret void2630//2631// CHECK-EH-11-LABEL: @_Z6test21v(2632// CHECK-EH-11-NEXT:  entry:2633// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42634// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12635// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42636// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12637// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2638// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12639// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12640// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2641// CHECK-EH-11:       nrvo.unused:2642// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2643// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2644// CHECK-EH-11:       nrvo.skipdtor:2645// CHECK-EH-11-NEXT:    ret void2646//2647const volatile X test21() { // http://wg21.link/p2025r2#ex-192648  X x;2649  return x; // NRVO happens2650}2651 2652// CHECK-LABEL: @_Z6test22v(2653// CHECK-NEXT:  entry:2654// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42655// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 12656// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42657// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])2658// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])2659// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR4]]2660// CHECK-NEXT:    ret void2661//2662// CHECK-EH-03-LABEL: @_Z6test22v(2663// CHECK-EH-03-NEXT:  entry:2664// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42665// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 12666// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 42667// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 42668// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42669// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])2670// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])2671// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]2672// CHECK-EH-03:       invoke.cont:2673// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])2674// CHECK-EH-03-NEXT:    ret void2675// CHECK-EH-03:       lpad:2676// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }2677// CHECK-EH-03-NEXT:            cleanup2678// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 02679// CHECK-EH-03-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 42680// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 12681// CHECK-EH-03-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 42682// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])2683// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]2684// CHECK-EH-03:       invoke.cont1:2685// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]2686// CHECK-EH-03:       eh.resume:2687// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 42688// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 42689// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 02690// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 12691// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]2692// CHECK-EH-03:       terminate.lpad:2693// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { ptr, i32 }2694// CHECK-EH-03-NEXT:            catch ptr null2695// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 02696// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP4]]) #[[ATTR6]]2697// CHECK-EH-03-NEXT:    unreachable2698//2699// CHECK-EH-11-LABEL: @_Z6test22v(2700// CHECK-EH-11-NEXT:  entry:2701// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42702// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 12703// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 42704// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 42705// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42706// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]])2707// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]])2708// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]2709// CHECK-EH-11:       invoke.cont:2710// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]2711// CHECK-EH-11-NEXT:    ret void2712// CHECK-EH-11:       lpad:2713// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }2714// CHECK-EH-11-NEXT:            cleanup2715// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 02716// CHECK-EH-11-NEXT:    store ptr [[TMP1]], ptr [[EXN_SLOT]], align 42717// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 12718// CHECK-EH-11-NEXT:    store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 42719// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]]2720// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]2721// CHECK-EH-11:       eh.resume:2722// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 42723// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 42724// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 02725// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 12726// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL1]]2727//2728X test22() { // http://wg21.link/p2025r2#ex-192729  volatile X x;2730  return x; // NRVO is impossible2731}2732 2733// CHECK-LABEL: @_Z6test23b(2734// CHECK-NEXT:  entry:2735// CHECK-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42736// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 12737// CHECK-NEXT:    [[NRVO:%.*]] = alloca i1, align 12738// CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 12739// CHECK-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42740// CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i82741// CHECK-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 12742// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 12743// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i12744// CHECK-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2745// CHECK:       if.then:2746// CHECK-NEXT:    store i1 false, ptr [[NRVO]], align 12747// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2748// CHECK-NEXT:    store i1 true, ptr [[NRVO]], align 12749// CHECK-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12750// CHECK-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2751// CHECK:       nrvo.unused:2752// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]]2753// CHECK-NEXT:    br label [[NRVO_SKIPDTOR]]2754// CHECK:       nrvo.skipdtor:2755// CHECK-NEXT:    br label [[RETURN:%.*]]2756// CHECK:       if.end:2757// CHECK-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2758// CHECK-NEXT:    call void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2759// CHECK-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR4]]2760// CHECK-NEXT:    br label [[RETURN]]2761// CHECK:       return:2762// CHECK-NEXT:    ret void2763//2764// CHECK-EH-03-LABEL: @_Z6test23b(2765// CHECK-EH-03-NEXT:  entry:2766// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42767// CHECK-EH-03-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 12768// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 12769// CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 12770// CHECK-EH-03-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 42771// CHECK-EH-03-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 42772// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42773// CHECK-EH-03-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i82774// CHECK-EH-03-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 12775// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 12776// CHECK-EH-03-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i12777// CHECK-EH-03-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2778// CHECK-EH-03:       if.then:2779// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 12780// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2781// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12782// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12783// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2784// CHECK-EH-03:       nrvo.unused:2785// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2786// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]2787// CHECK-EH-03:       nrvo.skipdtor:2788// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]2789// CHECK-EH-03:       if.end:2790// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2791// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2792// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]2793// CHECK-EH-03:       invoke.cont:2794// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2795// CHECK-EH-03-NEXT:    br label [[RETURN]]2796// CHECK-EH-03:       lpad:2797// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }2798// CHECK-EH-03-NEXT:            cleanup2799// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 02800// CHECK-EH-03-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 42801// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 12802// CHECK-EH-03-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 42803// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2804// CHECK-EH-03-NEXT:            to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]2805// CHECK-EH-03:       invoke.cont1:2806// CHECK-EH-03-NEXT:    br label [[EH_RESUME:%.*]]2807// CHECK-EH-03:       return:2808// CHECK-EH-03-NEXT:    ret void2809// CHECK-EH-03:       eh.resume:2810// CHECK-EH-03-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 42811// CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 42812// CHECK-EH-03-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 02813// CHECK-EH-03-NEXT:    [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 12814// CHECK-EH-03-NEXT:    resume { ptr, i32 } [[LPAD_VAL2]]2815// CHECK-EH-03:       terminate.lpad:2816// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { ptr, i32 }2817// CHECK-EH-03-NEXT:            catch ptr null2818// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 02819// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]]2820// CHECK-EH-03-NEXT:    unreachable2821//2822// CHECK-EH-11-LABEL: @_Z6test23b(2823// CHECK-EH-11-NEXT:  entry:2824// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42825// CHECK-EH-11-NEXT:    [[B_ADDR:%.*]] = alloca i8, align 12826// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12827// CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 12828// CHECK-EH-11-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 42829// CHECK-EH-11-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 42830// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42831// CHECK-EH-11-NEXT:    [[STOREDV:%.*]] = zext i1 [[B:%.*]] to i82832// CHECK-EH-11-NEXT:    store i8 [[STOREDV]], ptr [[B_ADDR]], align 12833// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 12834// CHECK-EH-11-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i12835// CHECK-EH-11-NEXT:    br i1 [[LOADEDV]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]2836// CHECK-EH-11:       if.then:2837// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12838// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2839// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12840// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12841// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2842// CHECK-EH-11:       nrvo.unused:2843// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2844// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2845// CHECK-EH-11:       nrvo.skipdtor:2846// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]2847// CHECK-EH-11:       if.end:2848// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2849// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]])2850// CHECK-EH-11-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]2851// CHECK-EH-11:       invoke.cont:2852// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]]2853// CHECK-EH-11-NEXT:    br label [[RETURN]]2854// CHECK-EH-11:       lpad:2855// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }2856// CHECK-EH-11-NEXT:            cleanup2857// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 02858// CHECK-EH-11-NEXT:    store ptr [[TMP2]], ptr [[EXN_SLOT]], align 42859// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 12860// CHECK-EH-11-NEXT:    store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 42861// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]]2862// CHECK-EH-11-NEXT:    br label [[EH_RESUME:%.*]]2863// CHECK-EH-11:       return:2864// CHECK-EH-11-NEXT:    ret void2865// CHECK-EH-11:       eh.resume:2866// CHECK-EH-11-NEXT:    [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 42867// CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 42868// CHECK-EH-11-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 02869// CHECK-EH-11-NEXT:    [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 12870// CHECK-EH-11-NEXT:    resume { ptr, i32 } [[LPAD_VAL1]]2871//2872X test23(bool b) { // http://wg21.link/p2025r2#ex-192873  if (b) {2874    const X x;2875    return x; // NRVO happens2876  }2877  volatile X y;2878  return y; // NRVO is impossible2879}2880 2881#ifdef __EXCEPTIONS2882// CHECK-EH-03-LABEL: @_Z6test24v(2883// CHECK-EH-03-NEXT:  entry:2884// CHECK-EH-03-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42885// CHECK-EH-03-NEXT:    [[NRVO:%.*]] = alloca i1, align 12886// CHECK-EH-03-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42887// CHECK-EH-03-NEXT:    store i1 false, ptr [[NRVO]], align 12888// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2889// CHECK-EH-03-NEXT:    store i1 true, ptr [[NRVO]], align 12890// CHECK-EH-03-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12891// CHECK-EH-03-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2892// CHECK-EH-03:       nrvo.unused:2893// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2894// CHECK-EH-03-NEXT:    br label [[NRVO_SKIPDTOR]]2895// CHECK-EH-03:       nrvo.skipdtor:2896// CHECK-EH-03-NEXT:    ret void2897//2898// CHECK-EH-11-LABEL: @_Z6test24v(2899// CHECK-EH-11-NEXT:  entry:2900// CHECK-EH-11-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 42901// CHECK-EH-11-NEXT:    [[NRVO:%.*]] = alloca i1, align 12902// CHECK-EH-11-NEXT:    store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 42903// CHECK-EH-11-NEXT:    store i1 false, ptr [[NRVO]], align 12904// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])2905// CHECK-EH-11-NEXT:    store i1 true, ptr [[NRVO]], align 12906// CHECK-EH-11-NEXT:    [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 12907// CHECK-EH-11-NEXT:    br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]]2908// CHECK-EH-11:       nrvo.unused:2909// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]]2910// CHECK-EH-11-NEXT:    br label [[NRVO_SKIPDTOR]]2911// CHECK-EH-11:       nrvo.skipdtor:2912// CHECK-EH-11-NEXT:    ret void2913//2914X test24() { // http://wg21.link/p2025r2#ex-202915  X x;2916  if (&x == &OuterX)2917    throw 0;2918  return x; // NRVO happens2919}2920#endif2921 2922#ifdef CXX112923template <bool B>2924X test25() {2925  X x;2926  if constexpr (B) {2927    return x; // FIXME: NRVO could happen when B == true, but doesn't2928  } else {2929    return X();2930  }2931}2932 2933// CHECK-EH-11-LABEL: @_Z17test25instantiatev(2934// CHECK-EH-11-NEXT:  entry:2935// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 12936// CHECK-EH-11-NEXT:    [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 12937// CHECK-EH-11-NEXT:    call void @_Z6test25ILb1EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]])2938// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]]2939// CHECK-EH-11-NEXT:    call void @_Z6test25ILb0EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]])2940// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]]2941// CHECK-EH-11-NEXT:    ret void2942//2943void test25instantiate() {2944  test25<true>();2945  test25<false>();2946}2947#endif2948