1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s 3 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s 4 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -DCXX11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s 5 6 // Test code generation for the named return value optimization. 7 class X { 8 public: 9 X(); 10 X(const X&); 11 X(const volatile X &); 12 ~X(); 13 }; 14 15 template<typename T> struct Y { 16 Y(); 17 static Y f() { 18 Y y; 19 return y; 20 } 21 }; 22 23 void ConsumeX(X x); 24 extern X OuterX; 25 26 // CHECK-LABEL: @_Z5test0v( 27 // CHECK-NEXT: entry: 28 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] 29 // CHECK-NEXT: ret void 30 // 31 // CHECK-EH-LABEL: @_Z5test0v( 32 // CHECK-EH-NEXT: entry: 33 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 34 // CHECK-EH-NEXT: ret void 35 // 36 X test0() { // http://wg21.link/p2025r2#ex-2 37 X x; 38 return x; // NRVO happens 39 } 40 41 // CHECK-LABEL: @_Z5test1b( 42 // CHECK-NEXT: entry: 43 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 44 // CHECK-NEXT: ret void 45 // 46 // CHECK-EH-LABEL: @_Z5test1b( 47 // CHECK-EH-NEXT: entry: 48 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 49 // CHECK-EH-NEXT: ret void 50 // 51 X test1(bool B) { 52 X x; 53 if (B) 54 return (x); // NRVO happens 55 return x; // NRVO happens 56 } 57 58 // CHECK-LABEL: @_Z5test2b( 59 // CHECK-NEXT: entry: 60 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 61 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 62 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 63 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 64 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 65 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 66 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 67 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 68 // CHECK-NEXT: [[Y_X:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 69 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y_X]]) #[[ATTR5]] 70 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 71 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 72 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 73 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 74 // CHECK-NEXT: ret void 75 // 76 // CHECK-EH-03-LABEL: @_Z5test2b( 77 // CHECK-EH-03-NEXT: entry: 78 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 79 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 80 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 81 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 82 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 83 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 84 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 85 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 86 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 87 // CHECK-EH-03: invoke.cont: 88 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 89 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]]) 90 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]] 91 // CHECK-EH-03: lpad: 92 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 93 // CHECK-EH-03-NEXT: cleanup 94 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 95 // CHECK-EH-03: lpad1: 96 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 97 // CHECK-EH-03-NEXT: cleanup 98 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 99 // CHECK-EH-03-NEXT: to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]] 100 // CHECK-EH-03: cleanup: 101 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 102 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] 103 // CHECK-EH-03: invoke.cont4: 104 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 105 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 106 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 107 // CHECK-EH-03-NEXT: ret void 108 // CHECK-EH-03: ehcleanup: 109 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD]] ], [ [[TMP4]], [[LPAD1]] ] 110 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 111 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 112 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[TERMINATE_LPAD]] 113 // CHECK-EH-03: invoke.cont9: 114 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 115 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[DOTPN]] 116 // CHECK-EH-03: terminate.lpad: 117 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } 118 // CHECK-EH-03-NEXT: catch i8* null 119 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0 120 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8:[0-9]+]] 121 // CHECK-EH-03-NEXT: unreachable 122 // 123 // CHECK-EH-11-LABEL: @_Z5test2b( 124 // CHECK-EH-11-NEXT: entry: 125 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 126 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 127 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 128 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 129 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 130 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 131 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 132 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 133 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 134 // CHECK-EH-11: invoke.cont: 135 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 136 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]]) 137 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]] 138 // CHECK-EH-11: lpad: 139 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 140 // CHECK-EH-11-NEXT: cleanup 141 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 142 // CHECK-EH-11: lpad1: 143 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 144 // CHECK-EH-11-NEXT: cleanup 145 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 146 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 147 // CHECK-EH-11: cleanup: 148 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 149 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 150 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 151 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 152 // CHECK-EH-11-NEXT: ret void 153 // CHECK-EH-11: ehcleanup: 154 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD1]] ], [ [[TMP3]], [[LPAD]] ] 155 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 156 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 157 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 158 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN]] 159 // 160 X test2(bool B) { 161 X x; 162 X y; 163 if (B) 164 return y; // NRVO is impossible 165 return x; // NRVO is impossible 166 } 167 168 // CHECK-LABEL: @_Z5test3b( 169 // CHECK-NEXT: entry: 170 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 171 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 172 // CHECK: if.then: 173 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 174 // CHECK-NEXT: br label [[RETURN:%.*]] 175 // CHECK: if.end: 176 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 177 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 178 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 179 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 180 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 181 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 182 // CHECK-NEXT: br label [[RETURN]] 183 // CHECK: return: 184 // CHECK-NEXT: ret void 185 // 186 // CHECK-EH-03-LABEL: @_Z5test3b( 187 // CHECK-EH-03-NEXT: entry: 188 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 189 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 190 // CHECK-EH-03: if.then: 191 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 192 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 193 // CHECK-EH-03: if.end: 194 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 195 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 196 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 197 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 198 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 199 // CHECK-EH-03: invoke.cont: 200 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 201 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 202 // CHECK-EH-03-NEXT: br label [[RETURN]] 203 // CHECK-EH-03: lpad: 204 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 205 // CHECK-EH-03-NEXT: cleanup 206 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 207 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 208 // CHECK-EH-03: invoke.cont1: 209 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 210 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 211 // CHECK-EH-03: return: 212 // CHECK-EH-03-NEXT: ret void 213 // CHECK-EH-03: terminate.lpad: 214 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 215 // CHECK-EH-03-NEXT: catch i8* null 216 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 217 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 218 // CHECK-EH-03-NEXT: unreachable 219 // 220 // CHECK-EH-11-LABEL: @_Z5test3b( 221 // CHECK-EH-11-NEXT: entry: 222 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 223 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 224 // CHECK-EH-11: if.then: 225 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 226 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 227 // CHECK-EH-11: if.end: 228 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 229 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 230 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 231 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 232 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 233 // CHECK-EH-11: invoke.cont: 234 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 235 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 236 // CHECK-EH-11-NEXT: br label [[RETURN]] 237 // CHECK-EH-11: lpad: 238 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 239 // CHECK-EH-11-NEXT: cleanup 240 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 241 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 242 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 243 // CHECK-EH-11: return: 244 // CHECK-EH-11-NEXT: ret void 245 // 246 X test3(bool B) { // http://wg21.link/p2025r2#ex-4 247 if (B) { 248 X y; 249 return y; // NRVO happens 250 } 251 X x; 252 return x; // FIXME: NRVO could happen, but doesn't 253 } 254 255 extern "C" void exit(int) throw(); 256 257 // CHECK-LABEL: @_Z5test4b( 258 // CHECK-NEXT: entry: 259 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 260 // CHECK-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 261 // CHECK: nrvo.unused: 262 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 263 // CHECK-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] 264 // CHECK-NEXT: unreachable 265 // CHECK: return: 266 // CHECK-NEXT: ret void 267 // 268 // CHECK-EH-03-LABEL: @_Z5test4b( 269 // CHECK-EH-03-NEXT: entry: 270 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 271 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 272 // CHECK-EH-03: nrvo.unused: 273 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 274 // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 275 // CHECK-EH-03-NEXT: unreachable 276 // CHECK-EH-03: return: 277 // CHECK-EH-03-NEXT: ret void 278 // 279 // CHECK-EH-11-LABEL: @_Z5test4b( 280 // CHECK-EH-11-NEXT: entry: 281 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 282 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 283 // CHECK-EH-11: nrvo.unused: 284 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 285 // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 286 // CHECK-EH-11-NEXT: unreachable 287 // CHECK-EH-11: return: 288 // CHECK-EH-11-NEXT: ret void 289 // 290 X test4(bool B) { 291 { 292 X x; 293 if (B) 294 return x; // NRVO happens 295 } 296 exit(1); 297 } 298 299 #ifdef __EXCEPTIONS 300 void may_throw(); 301 // CHECK-EH-03-LABEL: @_Z5test5v( 302 // CHECK-EH-03-NEXT: entry: 303 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 304 // CHECK-EH-03-NEXT: invoke void @_Z9may_throwv() 305 // CHECK-EH-03-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]] 306 // CHECK-EH-03: lpad: 307 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 308 // CHECK-EH-03-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 309 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0 310 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1 311 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]] 312 // CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]] 313 // CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 314 // CHECK-EH-03: catch: 315 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 316 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 317 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]] 318 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X* 319 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]]) 320 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 321 // CHECK-EH-03: invoke.cont1: 322 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]] 323 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 324 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 325 // CHECK-EH-03: invoke.cont3: 326 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 327 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]] 328 // CHECK-EH-03: lpad2: 329 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 330 // CHECK-EH-03-NEXT: cleanup 331 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 332 // CHECK-EH-03-NEXT: to label [[EHCLEANUP:%.*]] unwind label [[TERMINATE_LPAD]] 333 // CHECK-EH-03: invoke.cont5: 334 // CHECK-EH-03-NEXT: call void @__cxa_end_catch() 335 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 336 // CHECK-EH-03-NEXT: ret void 337 // CHECK-EH-03: lpad4: 338 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } 339 // CHECK-EH-03-NEXT: cleanup 340 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 341 // CHECK-EH-03: ehcleanup: 342 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP9]], [[LPAD4]] ], [ [[TMP8]], [[LPAD2]] ] 343 // CHECK-EH-03-NEXT: invoke void @__cxa_end_catch() 344 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]] 345 // CHECK-EH-03: invoke.cont7: 346 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 347 // CHECK-EH-03-NEXT: br label [[EH_RESUME]] 348 // CHECK-EH-03: try.cont: 349 // CHECK-EH-03-NEXT: unreachable 350 // CHECK-EH-03: eh.resume: 351 // CHECK-EH-03-NEXT: [[LPAD_VAL11_MERGED:%.*]] = phi { i8*, i32 } [ [[DOTPN]], [[INVOKE_CONT7]] ], [ [[TMP0]], [[LPAD]] ] 352 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL11_MERGED]] 353 // CHECK-EH-03: terminate.lpad: 354 // CHECK-EH-03-NEXT: [[TMP10:%.*]] = landingpad { i8*, i32 } 355 // CHECK-EH-03-NEXT: catch i8* null 356 // CHECK-EH-03-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0 357 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP11]]) #[[ATTR8]] 358 // CHECK-EH-03-NEXT: unreachable 359 // 360 // CHECK-EH-11-LABEL: @_Z5test5v( 361 // CHECK-EH-11-NEXT: entry: 362 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 363 // CHECK-EH-11-NEXT: invoke void @_Z9may_throwv() 364 // CHECK-EH-11-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]] 365 // CHECK-EH-11: lpad: 366 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 367 // CHECK-EH-11-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 368 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0 369 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1 370 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]] 371 // CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]] 372 // CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 373 // CHECK-EH-11: catch: 374 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 375 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 376 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]] 377 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X* 378 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]]) 379 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 380 // CHECK-EH-11: invoke.cont1: 381 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]] 382 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 383 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 384 // CHECK-EH-11: invoke.cont3: 385 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 386 // CHECK-EH-11-NEXT: call void @__cxa_end_catch() 387 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 388 // CHECK-EH-11-NEXT: ret void 389 // CHECK-EH-11: lpad2: 390 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 391 // CHECK-EH-11-NEXT: cleanup 392 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 393 // CHECK-EH-11-NEXT: invoke void @__cxa_end_catch() 394 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]] 395 // CHECK-EH-11: invoke.cont4: 396 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 397 // CHECK-EH-11-NEXT: br label [[EH_RESUME]] 398 // CHECK-EH-11: try.cont: 399 // CHECK-EH-11-NEXT: unreachable 400 // CHECK-EH-11: eh.resume: 401 // CHECK-EH-11-NEXT: [[LPAD_VAL7_MERGED:%.*]] = phi { i8*, i32 } [ [[TMP8]], [[INVOKE_CONT4]] ], [ [[TMP0]], [[LPAD]] ] 402 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL7_MERGED]] 403 // CHECK-EH-11: terminate.lpad: 404 // CHECK-EH-11-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } 405 // CHECK-EH-11-NEXT: catch i8* null 406 // CHECK-EH-11-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 407 // CHECK-EH-11-NEXT: call void @__clang_call_terminate(i8* [[TMP10]]) #[[ATTR8:[0-9]+]] 408 // CHECK-EH-11-NEXT: unreachable 409 // 410 X test5() { // http://wg21.link/p2025r2#ex-14 411 try { 412 may_throw(); 413 } catch (X x) { 414 return x; // FIXME: NRVO could happen, but doesn't 415 } 416 } 417 #endif 418 419 // rdar://problem/10430868 420 // CHECK-LABEL: @_Z5test6v( 421 // CHECK-NEXT: entry: 422 // CHECK-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 423 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 424 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 425 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 426 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 427 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 428 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 429 // CHECK-NEXT: ret void 430 // 431 // CHECK-EH-03-LABEL: @_Z5test6v( 432 // CHECK-EH-03-NEXT: entry: 433 // CHECK-EH-03-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 434 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 435 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 436 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 437 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 438 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 439 // CHECK-EH-03: invoke.cont: 440 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 441 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 442 // CHECK-EH-03-NEXT: ret void 443 // CHECK-EH-03: lpad: 444 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 445 // CHECK-EH-03-NEXT: cleanup 446 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 447 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 448 // CHECK-EH-03: invoke.cont1: 449 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 450 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 451 // CHECK-EH-03: terminate.lpad: 452 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 453 // CHECK-EH-03-NEXT: catch i8* null 454 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 455 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 456 // CHECK-EH-03-NEXT: unreachable 457 // 458 // CHECK-EH-11-LABEL: @_Z5test6v( 459 // CHECK-EH-11-NEXT: entry: 460 // CHECK-EH-11-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 461 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 462 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 463 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 464 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 465 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 466 // CHECK-EH-11: invoke.cont: 467 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]] 468 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 469 // CHECK-EH-11-NEXT: ret void 470 // CHECK-EH-11: lpad: 471 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 472 // CHECK-EH-11-NEXT: cleanup 473 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]] 474 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 475 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 476 // 477 X test6() { 478 X a __attribute__((aligned(8))); 479 return a; // NRVO is impossible 480 } 481 482 // CHECK-LABEL: @_Z5test7b( 483 // CHECK-NEXT: entry: 484 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 485 // CHECK-NEXT: ret void 486 // 487 // CHECK-EH-LABEL: @_Z5test7b( 488 // CHECK-EH-NEXT: entry: 489 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 490 // CHECK-EH-NEXT: ret void 491 // 492 X test7(bool b) { 493 if (b) { 494 X x; 495 return x; // NRVO happens 496 } 497 return X(); 498 } 499 500 // CHECK-LABEL: @_Z5test8b( 501 // CHECK-NEXT: entry: 502 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 503 // CHECK-NEXT: ret void 504 // 505 // CHECK-EH-LABEL: @_Z5test8b( 506 // CHECK-EH-NEXT: entry: 507 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 508 // CHECK-EH-NEXT: ret void 509 // 510 X test8(bool b) { 511 if (b) { 512 X x; 513 return x; // NRVO happens 514 } else { 515 X y; 516 return y; // NRVO happens 517 } 518 } 519 520 // CHECK-LABEL: @_Z5test9v( 521 // CHECK-NEXT: entry: 522 // CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 523 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0 524 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 525 // CHECK-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]]) 526 // CHECK-NEXT: unreachable 527 // 528 // CHECK-EH-LABEL: @_Z5test9v( 529 // CHECK-EH-NEXT: entry: 530 // CHECK-EH-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 531 // CHECK-EH-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0 532 // CHECK-EH-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 533 // CHECK-EH-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]]) 534 // CHECK-EH-NEXT: unreachable 535 // 536 Y<int> test9() { 537 Y<int>::f(); 538 } 539 540 // CHECK-LABEL: @_Z6test10b( 541 // CHECK-NEXT: entry: 542 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 543 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 544 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 545 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 546 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 547 // CHECK: if.then: 548 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 549 // CHECK-NEXT: br label [[CLEANUP:%.*]] 550 // CHECK: if.else: 551 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 552 // CHECK-NEXT: br label [[CLEANUP]] 553 // CHECK: cleanup: 554 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 555 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 556 // CHECK-NEXT: ret void 557 // 558 // CHECK-EH-03-LABEL: @_Z6test10b( 559 // CHECK-EH-03-NEXT: entry: 560 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 561 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 562 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 563 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 564 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 565 // CHECK-EH-03: if.then: 566 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 567 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 568 // CHECK-EH-03: lpad: 569 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 570 // CHECK-EH-03-NEXT: cleanup 571 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 572 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 573 // CHECK-EH-03: if.else: 574 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 575 // CHECK-EH-03-NEXT: to label [[CLEANUP]] unwind label [[LPAD]] 576 // CHECK-EH-03: cleanup: 577 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 578 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 579 // CHECK-EH-03-NEXT: ret void 580 // CHECK-EH-03: invoke.cont2: 581 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 582 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 583 // CHECK-EH-03: terminate.lpad: 584 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 585 // CHECK-EH-03-NEXT: catch i8* null 586 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 587 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 588 // CHECK-EH-03-NEXT: unreachable 589 // 590 // CHECK-EH-11-LABEL: @_Z6test10b( 591 // CHECK-EH-11-NEXT: entry: 592 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 593 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 594 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 595 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 596 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 597 // CHECK-EH-11: if.then: 598 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 599 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 600 // CHECK-EH-11: lpad: 601 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 602 // CHECK-EH-11-NEXT: cleanup 603 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 604 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 605 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 606 // CHECK-EH-11: if.else: 607 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 608 // CHECK-EH-11-NEXT: to label [[CLEANUP]] unwind label [[LPAD]] 609 // CHECK-EH-11: cleanup: 610 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 611 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 612 // CHECK-EH-11-NEXT: ret void 613 // 614 X test10(bool b) { // http://wg21.link/p2025r2#ex-3 615 X x; 616 if (b) 617 return x; // NRVO is impossible 618 else 619 return X(); 620 } 621 622 // CHECK-LABEL: @_Z6test11b( 623 // CHECK-NEXT: entry: 624 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 625 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 626 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 627 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 628 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 629 // CHECK: if.then: 630 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 631 // CHECK-NEXT: br label [[CLEANUP:%.*]] 632 // CHECK: if.end: 633 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 634 // CHECK-NEXT: br label [[CLEANUP]] 635 // CHECK: cleanup: 636 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 637 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 638 // CHECK-NEXT: ret void 639 // 640 // CHECK-EH-03-LABEL: @_Z6test11b( 641 // CHECK-EH-03-NEXT: entry: 642 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 643 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 644 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 645 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 646 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 647 // CHECK-EH-03: if.then: 648 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 649 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 650 // CHECK-EH-03: lpad: 651 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 652 // CHECK-EH-03-NEXT: cleanup 653 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 654 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 655 // CHECK-EH-03: if.end: 656 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 657 // CHECK-EH-03-NEXT: to label [[CLEANUP]] unwind label [[LPAD]] 658 // CHECK-EH-03: cleanup: 659 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 660 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 661 // CHECK-EH-03-NEXT: ret void 662 // CHECK-EH-03: invoke.cont2: 663 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 664 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 665 // CHECK-EH-03: terminate.lpad: 666 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 667 // CHECK-EH-03-NEXT: catch i8* null 668 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 669 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 670 // CHECK-EH-03-NEXT: unreachable 671 // 672 // CHECK-EH-11-LABEL: @_Z6test11b( 673 // CHECK-EH-11-NEXT: entry: 674 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 675 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 676 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 677 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 678 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 679 // CHECK-EH-11: if.then: 680 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 681 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 682 // CHECK-EH-11: lpad: 683 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 684 // CHECK-EH-11-NEXT: cleanup 685 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 686 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 687 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 688 // CHECK-EH-11: if.end: 689 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 690 // CHECK-EH-11-NEXT: to label [[CLEANUP]] unwind label [[LPAD]] 691 // CHECK-EH-11: cleanup: 692 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 693 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 694 // CHECK-EH-11-NEXT: ret void 695 // 696 X test11(bool b) { // http://wg21.link/p2025r2#ex-5 697 X x; 698 if (b) 699 return X(); 700 return x; // NRVO is impossible 701 } 702 703 // CHECK-LABEL: @_Z6test12b( 704 // CHECK-NEXT: entry: 705 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 706 // CHECK-NEXT: br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]] 707 // CHECK: nrvo.unused: 708 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 709 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 710 // CHECK-NEXT: br label [[RETURN]] 711 // CHECK: return: 712 // CHECK-NEXT: ret void 713 // 714 // CHECK-EH-03-LABEL: @_Z6test12b( 715 // CHECK-EH-03-NEXT: entry: 716 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 717 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]] 718 // CHECK-EH-03: nrvo.unused: 719 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 720 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 721 // CHECK-EH-03-NEXT: br label [[RETURN]] 722 // CHECK-EH-03: return: 723 // CHECK-EH-03-NEXT: ret void 724 // 725 // CHECK-EH-11-LABEL: @_Z6test12b( 726 // CHECK-EH-11-NEXT: entry: 727 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 728 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[NRVO_UNUSED:%.*]], label [[RETURN:%.*]] 729 // CHECK-EH-11: nrvo.unused: 730 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 731 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 732 // CHECK-EH-11-NEXT: br label [[RETURN]] 733 // CHECK-EH-11: return: 734 // CHECK-EH-11-NEXT: ret void 735 // 736 X test12(bool b) { // http://wg21.link/p2025r2#ex-6 737 do { 738 X x; 739 if (b) 740 break; 741 return x; // NRVO happens 742 } while (false); 743 return X(); 744 } 745 746 // CHECK-LABEL: @_Z6test13b( 747 // CHECK-NEXT: entry: 748 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 749 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 750 // CHECK: if.then: 751 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 752 // CHECK-NEXT: br label [[RETURN:%.*]] 753 // CHECK: if.end: 754 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 755 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 756 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 757 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 758 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 759 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 760 // CHECK-NEXT: br label [[RETURN]] 761 // CHECK: return: 762 // CHECK-NEXT: ret void 763 // 764 // CHECK-EH-03-LABEL: @_Z6test13b( 765 // CHECK-EH-03-NEXT: entry: 766 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 767 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 768 // CHECK-EH-03: if.then: 769 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 770 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 771 // CHECK-EH-03: if.end: 772 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 773 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 774 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 775 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 776 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 777 // CHECK-EH-03: invoke.cont: 778 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 779 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 780 // CHECK-EH-03-NEXT: br label [[RETURN]] 781 // CHECK-EH-03: lpad: 782 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 783 // CHECK-EH-03-NEXT: cleanup 784 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 785 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 786 // CHECK-EH-03: invoke.cont1: 787 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 788 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 789 // CHECK-EH-03: return: 790 // CHECK-EH-03-NEXT: ret void 791 // CHECK-EH-03: terminate.lpad: 792 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 793 // CHECK-EH-03-NEXT: catch i8* null 794 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 795 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 796 // CHECK-EH-03-NEXT: unreachable 797 // 798 // CHECK-EH-11-LABEL: @_Z6test13b( 799 // CHECK-EH-11-NEXT: entry: 800 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 801 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 802 // CHECK-EH-11: if.then: 803 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 804 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 805 // CHECK-EH-11: if.end: 806 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 807 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 808 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 809 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 810 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 811 // CHECK-EH-11: invoke.cont: 812 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 813 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 814 // CHECK-EH-11-NEXT: br label [[RETURN]] 815 // CHECK-EH-11: lpad: 816 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 817 // CHECK-EH-11-NEXT: cleanup 818 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 819 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 820 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 821 // CHECK-EH-11: return: 822 // CHECK-EH-11-NEXT: ret void 823 // 824 X test13(bool b) { // http://wg21.link/p2025r2#ex-7 825 if (b) 826 return X(); 827 X x; 828 return x; // FIXME: NRVO could happen, but doesn't 829 } 830 831 // CHECK-LABEL: @_Z6test14b( 832 // CHECK-NEXT: entry: 833 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 834 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 835 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 836 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 837 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 838 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 839 // CHECK: if.then: 840 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 841 // CHECK-NEXT: br label [[CLEANUP:%.*]] 842 // CHECK: if.end: 843 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 844 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 845 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 846 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 847 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 848 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 849 // CHECK-NEXT: br label [[CLEANUP]] 850 // CHECK: cleanup: 851 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 852 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 853 // CHECK-NEXT: ret void 854 // 855 // CHECK-EH-03-LABEL: @_Z6test14b( 856 // CHECK-EH-03-NEXT: entry: 857 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 858 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 859 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 860 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 861 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 862 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 863 // CHECK-EH-03: if.then: 864 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 865 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 866 // CHECK-EH-03: lpad: 867 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 868 // CHECK-EH-03-NEXT: cleanup 869 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7:%.*]] 870 // CHECK-EH-03: if.end: 871 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 872 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 873 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 874 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 875 // CHECK-EH-03: invoke.cont2: 876 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 877 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 878 // CHECK-EH-03: invoke.cont4: 879 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 880 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]] 881 // CHECK-EH-03: lpad1: 882 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 883 // CHECK-EH-03-NEXT: cleanup 884 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 885 // CHECK-EH-03: lpad3: 886 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 887 // CHECK-EH-03-NEXT: cleanup 888 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 889 // CHECK-EH-03-NEXT: to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]] 890 // CHECK-EH-03: invoke.cont5: 891 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 892 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 893 // CHECK-EH-03: ehcleanup: 894 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD1]] ], [ [[TMP4]], [[LPAD3]] ] 895 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 896 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7]] 897 // CHECK-EH-03: cleanup: 898 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 899 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 900 // CHECK-EH-03-NEXT: ret void 901 // CHECK-EH-03: ehcleanup7: 902 // CHECK-EH-03-NEXT: [[DOTPN13:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ] 903 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 904 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]] 905 // CHECK-EH-03: invoke.cont8: 906 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 907 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[DOTPN13]] 908 // CHECK-EH-03: terminate.lpad: 909 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } 910 // CHECK-EH-03-NEXT: catch i8* null 911 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0 912 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]] 913 // CHECK-EH-03-NEXT: unreachable 914 // 915 // CHECK-EH-11-LABEL: @_Z6test14b( 916 // CHECK-EH-11-NEXT: entry: 917 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 918 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 919 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 920 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 921 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 922 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 923 // CHECK-EH-11: if.then: 924 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 925 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 926 // CHECK-EH-11: lpad: 927 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 928 // CHECK-EH-11-NEXT: cleanup 929 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5:%.*]] 930 // CHECK-EH-11: if.end: 931 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 932 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 933 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 934 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 935 // CHECK-EH-11: invoke.cont2: 936 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 937 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 938 // CHECK-EH-11: invoke.cont4: 939 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 940 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 941 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 942 // CHECK-EH-11: lpad1: 943 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 944 // CHECK-EH-11-NEXT: cleanup 945 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 946 // CHECK-EH-11: lpad3: 947 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 948 // CHECK-EH-11-NEXT: cleanup 949 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 950 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 951 // CHECK-EH-11: ehcleanup: 952 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD3]] ], [ [[TMP3]], [[LPAD1]] ] 953 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 954 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5]] 955 // CHECK-EH-11: cleanup: 956 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 957 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 958 // CHECK-EH-11-NEXT: ret void 959 // CHECK-EH-11: ehcleanup5: 960 // CHECK-EH-11-NEXT: [[DOTPN10:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ] 961 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 962 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 963 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN10]] 964 // 965 X test14(bool b) { // http://wg21.link/p2025r2#ex-8 966 X x; 967 if (b) 968 return x; 969 X y; 970 return y; // FIXME: NRVO could happen, but doesn't 971 } 972 973 // CHECK-LABEL: @_Z6test15b( 974 // CHECK-NEXT: entry: 975 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 976 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 977 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 978 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 979 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 980 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 981 // CHECK: if.then: 982 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 983 // CHECK-NEXT: br label [[CLEANUP:%.*]] 984 // CHECK: if.end: 985 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 986 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 987 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 988 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 989 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 990 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 991 // CHECK-NEXT: br label [[CLEANUP]] 992 // CHECK: cleanup: 993 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 994 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 995 // CHECK-NEXT: ret void 996 // 997 // CHECK-EH-03-LABEL: @_Z6test15b( 998 // CHECK-EH-03-NEXT: entry: 999 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1000 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1001 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1002 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1003 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1004 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1005 // CHECK-EH-03: if.then: 1006 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1007 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 1008 // CHECK-EH-03: lpad: 1009 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1010 // CHECK-EH-03-NEXT: cleanup 1011 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7:%.*]] 1012 // CHECK-EH-03: if.end: 1013 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1014 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1015 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1016 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1017 // CHECK-EH-03: invoke.cont2: 1018 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1019 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1020 // CHECK-EH-03: invoke.cont4: 1021 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1022 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]] 1023 // CHECK-EH-03: lpad1: 1024 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1025 // CHECK-EH-03-NEXT: cleanup 1026 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 1027 // CHECK-EH-03: lpad3: 1028 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 1029 // CHECK-EH-03-NEXT: cleanup 1030 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1031 // CHECK-EH-03-NEXT: to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]] 1032 // CHECK-EH-03: invoke.cont5: 1033 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1034 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1035 // CHECK-EH-03: ehcleanup: 1036 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD1]] ], [ [[TMP4]], [[LPAD3]] ] 1037 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1038 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7]] 1039 // CHECK-EH-03: cleanup: 1040 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1041 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1042 // CHECK-EH-03-NEXT: ret void 1043 // CHECK-EH-03: ehcleanup7: 1044 // CHECK-EH-03-NEXT: [[DOTPN13:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ] 1045 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1046 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]] 1047 // CHECK-EH-03: invoke.cont8: 1048 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1049 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[DOTPN13]] 1050 // CHECK-EH-03: terminate.lpad: 1051 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } 1052 // CHECK-EH-03-NEXT: catch i8* null 1053 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0 1054 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]] 1055 // CHECK-EH-03-NEXT: unreachable 1056 // 1057 // CHECK-EH-11-LABEL: @_Z6test15b( 1058 // CHECK-EH-11-NEXT: entry: 1059 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1060 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1061 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1062 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1063 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1064 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1065 // CHECK-EH-11: if.then: 1066 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1067 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD:%.*]] 1068 // CHECK-EH-11: lpad: 1069 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1070 // CHECK-EH-11-NEXT: cleanup 1071 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5:%.*]] 1072 // CHECK-EH-11: if.end: 1073 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1074 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1075 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1076 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1077 // CHECK-EH-11: invoke.cont2: 1078 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1079 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1080 // CHECK-EH-11: invoke.cont4: 1081 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1082 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1083 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1084 // CHECK-EH-11: lpad1: 1085 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1086 // CHECK-EH-11-NEXT: cleanup 1087 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 1088 // CHECK-EH-11: lpad3: 1089 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 1090 // CHECK-EH-11-NEXT: cleanup 1091 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1092 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 1093 // CHECK-EH-11: ehcleanup: 1094 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD3]] ], [ [[TMP3]], [[LPAD1]] ] 1095 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1096 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5]] 1097 // CHECK-EH-11: cleanup: 1098 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1099 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1100 // CHECK-EH-11-NEXT: ret void 1101 // CHECK-EH-11: ehcleanup5: 1102 // CHECK-EH-11-NEXT: [[DOTPN10:%.*]] = phi { i8*, i32 } [ [[TMP1]], [[LPAD]] ], [ [[DOTPN]], [[EHCLEANUP]] ] 1103 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1104 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1105 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN10]] 1106 // 1107 X test15(bool b) { // http://wg21.link/p2025r2#ex-15 1108 X x; 1109 if (b) 1110 return (x); 1111 X y; 1112 return ((y)); // FIXME: NRVO could happen, but doesn't 1113 } 1114 1115 #ifdef CXX11 1116 // CHECK-EH-11-LABEL: @_Z6test16v( 1117 // CHECK-EH-11-NEXT: entry: 1118 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1119 // CHECK-EH-11-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_X]], align 1 1120 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1121 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1122 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1123 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1124 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1125 // CHECK-EH-11: invoke.cont: 1126 // CHECK-EH-11-NEXT: invoke void @_Z8ConsumeX1X(%class.X* noundef nonnull [[AGG_TMP]]) 1127 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1128 // CHECK-EH-11: invoke.cont2: 1129 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR7]] 1130 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1131 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1132 // CHECK-EH-11-NEXT: ret void 1133 // CHECK-EH-11: lpad: 1134 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1135 // CHECK-EH-11-NEXT: cleanup 1136 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 1137 // CHECK-EH-11: lpad1: 1138 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 1139 // CHECK-EH-11-NEXT: cleanup 1140 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR7]] 1141 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 1142 // CHECK-EH-11: ehcleanup: 1143 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP2]], [[LPAD1]] ], [ [[TMP1]], [[LPAD]] ] 1144 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1145 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1146 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN]] 1147 // 1148 void test16() { // http://wg21.link/p2025r2#ex-9 1149 X x; 1150 ConsumeX([&] { 1151 X y(x); 1152 return y; // NRVO happens 1153 }()); 1154 } 1155 #endif 1156 1157 // CHECK-LABEL: @_Z6test17i( 1158 // CHECK-NEXT: entry: 1159 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3 1160 // CHECK-NEXT: br label [[WHILE_BODY:%.*]] 1161 // CHECK: impossible: 1162 // CHECK-NEXT: br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]] 1163 // CHECK: while.body.backedge: 1164 // CHECK-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]] 1165 // CHECK: while.body: 1166 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 1167 // CHECK-NEXT: switch i32 [[I]], label [[IF_END20:%.*]] [ 1168 // CHECK-NEXT: i32 0, label [[CLEANUP:%.*]] 1169 // CHECK-NEXT: i32 1, label [[IF_THEN7:%.*]] 1170 // CHECK-NEXT: i32 2, label [[IF_THEN10:%.*]] 1171 // CHECK-NEXT: i32 3, label [[IF_THEN13:%.*]] 1172 // CHECK-NEXT: i32 4, label [[IF_THEN16:%.*]] 1173 // CHECK-NEXT: i32 5, label [[CLEANUP]] 1174 // CHECK-NEXT: ] 1175 // CHECK: if.then7: 1176 // CHECK-NEXT: br label [[CLEANUP]] 1177 // CHECK: if.then10: 1178 // CHECK-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3]] 1179 // CHECK: if.then13: 1180 // CHECK-NEXT: br label [[CLEANUP]] 1181 // CHECK: if.then16: 1182 // CHECK-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] 1183 // CHECK-NEXT: br label [[IF_END20]] 1184 // CHECK: if.end20: 1185 // CHECK-NEXT: br label [[CLEANUP]] 1186 // CHECK: cleanup: 1187 // CHECK-NEXT: [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ] 1188 // CHECK-NEXT: [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ] 1189 // CHECK-NEXT: br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1190 // CHECK: nrvo.unused: 1191 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 1192 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 1193 // CHECK: nrvo.skipdtor: 1194 // CHECK-NEXT: switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [ 1195 // CHECK-NEXT: i32 0, label [[WHILE_BODY_BACKEDGE]] 1196 // CHECK-NEXT: i32 1, label [[RETURN:%.*]] 1197 // CHECK-NEXT: i32 4, label [[RETURN_SINK_SPLIT]] 1198 // CHECK-NEXT: i32 3, label [[WHILE_BODY_BACKEDGE]] 1199 // CHECK-NEXT: i32 2, label [[IMPOSSIBLE:%.*]] 1200 // CHECK-NEXT: ] 1201 // CHECK: return.sink.split: 1202 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 1203 // CHECK-NEXT: br label [[RETURN]] 1204 // CHECK: return: 1205 // CHECK-NEXT: ret void 1206 // CHECK: unreachable: 1207 // CHECK-NEXT: unreachable 1208 // 1209 // CHECK-EH-03-LABEL: @_Z6test17i( 1210 // CHECK-EH-03-NEXT: entry: 1211 // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3 1212 // CHECK-EH-03-NEXT: br label [[WHILE_BODY:%.*]] 1213 // CHECK-EH-03: impossible: 1214 // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]] 1215 // CHECK-EH-03: while.body.backedge: 1216 // CHECK-EH-03-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]] 1217 // CHECK-EH-03: while.body: 1218 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1219 // CHECK-EH-03-NEXT: switch i32 [[I]], label [[IF_END20:%.*]] [ 1220 // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP:%.*]] 1221 // CHECK-EH-03-NEXT: i32 1, label [[IF_THEN7:%.*]] 1222 // CHECK-EH-03-NEXT: i32 2, label [[IF_THEN10:%.*]] 1223 // CHECK-EH-03-NEXT: i32 3, label [[IF_THEN13:%.*]] 1224 // CHECK-EH-03-NEXT: i32 4, label [[IF_THEN16:%.*]] 1225 // CHECK-EH-03-NEXT: i32 5, label [[CLEANUP]] 1226 // CHECK-EH-03-NEXT: ] 1227 // CHECK-EH-03: if.then7: 1228 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1229 // CHECK-EH-03: if.then10: 1230 // CHECK-EH-03-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3]] 1231 // CHECK-EH-03: if.then13: 1232 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1233 // CHECK-EH-03: if.then16: 1234 // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 1235 // CHECK-EH-03-NEXT: br label [[IF_END20]] 1236 // CHECK-EH-03: if.end20: 1237 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1238 // CHECK-EH-03: cleanup: 1239 // CHECK-EH-03-NEXT: [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ] 1240 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ] 1241 // CHECK-EH-03-NEXT: br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1242 // CHECK-EH-03: nrvo.unused: 1243 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1244 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 1245 // CHECK-EH-03: nrvo.skipdtor: 1246 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [ 1247 // CHECK-EH-03-NEXT: i32 0, label [[WHILE_BODY_BACKEDGE]] 1248 // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] 1249 // CHECK-EH-03-NEXT: i32 4, label [[RETURN_SINK_SPLIT]] 1250 // CHECK-EH-03-NEXT: i32 3, label [[WHILE_BODY_BACKEDGE]] 1251 // CHECK-EH-03-NEXT: i32 2, label [[IMPOSSIBLE:%.*]] 1252 // CHECK-EH-03-NEXT: ] 1253 // CHECK-EH-03: return.sink.split: 1254 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1255 // CHECK-EH-03-NEXT: br label [[RETURN]] 1256 // CHECK-EH-03: return: 1257 // CHECK-EH-03-NEXT: ret void 1258 // CHECK-EH-03: unreachable: 1259 // CHECK-EH-03-NEXT: unreachable 1260 // 1261 // CHECK-EH-11-LABEL: @_Z6test17i( 1262 // CHECK-EH-11-NEXT: entry: 1263 // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 3 1264 // CHECK-EH-11-NEXT: br label [[WHILE_BODY:%.*]] 1265 // CHECK-EH-11: impossible: 1266 // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[RETURN_SINK_SPLIT:%.*]], label [[WHILE_BODY_BACKEDGE:%.*]] 1267 // CHECK-EH-11: while.body.backedge: 1268 // CHECK-EH-11-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP3:![0-9]+]] 1269 // CHECK-EH-11: while.body: 1270 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1271 // CHECK-EH-11-NEXT: switch i32 [[I]], label [[IF_END20:%.*]] [ 1272 // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP:%.*]] 1273 // CHECK-EH-11-NEXT: i32 1, label [[IF_THEN7:%.*]] 1274 // CHECK-EH-11-NEXT: i32 2, label [[IF_THEN10:%.*]] 1275 // CHECK-EH-11-NEXT: i32 3, label [[IF_THEN13:%.*]] 1276 // CHECK-EH-11-NEXT: i32 4, label [[IF_THEN16:%.*]] 1277 // CHECK-EH-11-NEXT: i32 5, label [[CLEANUP]] 1278 // CHECK-EH-11-NEXT: ] 1279 // CHECK-EH-11: if.then7: 1280 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1281 // CHECK-EH-11: if.then10: 1282 // CHECK-EH-11-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3]] 1283 // CHECK-EH-11: if.then13: 1284 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1285 // CHECK-EH-11: if.then16: 1286 // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 1287 // CHECK-EH-11-NEXT: br label [[IF_END20]] 1288 // CHECK-EH-11: if.end20: 1289 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1290 // CHECK-EH-11: cleanup: 1291 // CHECK-EH-11-NEXT: [[NRVO_0:%.*]] = phi i1 [ false, [[IF_THEN7]] ], [ false, [[IF_THEN10]] ], [ false, [[IF_THEN13]] ], [ false, [[IF_END20]] ], [ true, [[WHILE_BODY]] ], [ true, [[WHILE_BODY]] ] 1292 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT_0:%.*]] = phi i32 [ 4, [[IF_THEN7]] ], [ 3, [[IF_THEN10]] ], [ 2, [[IF_THEN13]] ], [ 0, [[IF_END20]] ], [ 1, [[WHILE_BODY]] ], [ 1, [[WHILE_BODY]] ] 1293 // CHECK-EH-11-NEXT: br i1 [[NRVO_0]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1294 // CHECK-EH-11: nrvo.unused: 1295 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 1296 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 1297 // CHECK-EH-11: nrvo.skipdtor: 1298 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST_SLOT_0]], label [[UNREACHABLE:%.*]] [ 1299 // CHECK-EH-11-NEXT: i32 0, label [[WHILE_BODY_BACKEDGE]] 1300 // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] 1301 // CHECK-EH-11-NEXT: i32 4, label [[RETURN_SINK_SPLIT]] 1302 // CHECK-EH-11-NEXT: i32 3, label [[WHILE_BODY_BACKEDGE]] 1303 // CHECK-EH-11-NEXT: i32 2, label [[IMPOSSIBLE:%.*]] 1304 // CHECK-EH-11-NEXT: ] 1305 // CHECK-EH-11: return.sink.split: 1306 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1307 // CHECK-EH-11-NEXT: br label [[RETURN]] 1308 // CHECK-EH-11: return: 1309 // CHECK-EH-11-NEXT: ret void 1310 // CHECK-EH-11: unreachable: 1311 // CHECK-EH-11-NEXT: unreachable 1312 // 1313 X test17(int i) { // http://wg21.link/p2025r2#ex-10 1314 if (false) { 1315 impossible: 1316 if (i == 3) 1317 return X(); 1318 } 1319 1320 while (true) { 1321 X x; 1322 if (i == 0) 1323 return x; // NRVO happens 1324 if (i == 1) 1325 break; 1326 if (i == 2) 1327 continue; 1328 if (i == 3) 1329 goto impossible; 1330 if (i == 4) 1331 exit(1); 1332 if (i == 5) 1333 return x; // NRVO happens 1334 } 1335 return X(); 1336 } 1337 1338 // CHECK-LABEL: @_Z6test18i( 1339 // CHECK-NEXT: entry: 1340 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1341 // CHECK-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 1342 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 1343 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0 1344 // CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 1345 // CHECK: nrvo.unused: 1346 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 1347 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1348 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1349 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1350 // CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I]], 1 1351 // CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT7_CRITEDGE:%.*]] 1352 // CHECK: if.then2: 1353 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1354 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1355 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1356 // CHECK-NEXT: br label [[RETURN]] 1357 // CHECK: cleanup.cont7.critedge: 1358 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1359 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1360 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0 1361 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 1362 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]] 1363 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]] 1364 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR5]] 1365 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 1366 // CHECK-NEXT: br label [[RETURN]] 1367 // CHECK: return: 1368 // CHECK-NEXT: ret void 1369 // 1370 // CHECK-EH-03-LABEL: @_Z6test18i( 1371 // CHECK-EH-03-NEXT: entry: 1372 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1373 // CHECK-EH-03-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 1374 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1375 // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0 1376 // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 1377 // CHECK-EH-03: nrvo.unused: 1378 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1379 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1380 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1381 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1382 // CHECK-EH-03-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I]], 1 1383 // CHECK-EH-03-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT8_CRITEDGE:%.*]] 1384 // CHECK-EH-03: if.then2: 1385 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1386 // CHECK-EH-03-NEXT: to label [[CLEANUP4:%.*]] unwind label [[LPAD:%.*]] 1387 // CHECK-EH-03: lpad: 1388 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1389 // CHECK-EH-03-NEXT: cleanup 1390 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1391 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1392 // CHECK-EH-03: cleanup4: 1393 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1394 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1395 // CHECK-EH-03-NEXT: br i1 [[CMP1]], label [[RETURN]], label [[CLEANUP_CONT8:%.*]] 1396 // CHECK-EH-03: cleanup.cont8.critedge: 1397 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1398 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1399 // CHECK-EH-03-NEXT: br label [[CLEANUP_CONT8]] 1400 // CHECK-EH-03: cleanup.cont8: 1401 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0 1402 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1403 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1404 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1405 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT10:%.*]] unwind label [[LPAD9:%.*]] 1406 // CHECK-EH-03: invoke.cont10: 1407 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1408 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1409 // CHECK-EH-03-NEXT: br label [[RETURN]] 1410 // CHECK-EH-03: invoke.cont5: 1411 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1412 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1413 // CHECK-EH-03: lpad9: 1414 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1415 // CHECK-EH-03-NEXT: cleanup 1416 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1417 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT12:%.*]] unwind label [[TERMINATE_LPAD]] 1418 // CHECK-EH-03: invoke.cont12: 1419 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1420 // CHECK-EH-03-NEXT: br label [[EH_RESUME]] 1421 // CHECK-EH-03: return: 1422 // CHECK-EH-03-NEXT: ret void 1423 // CHECK-EH-03: eh.resume: 1424 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[INVOKE_CONT12]] ], [ [[TMP1]], [[INVOKE_CONT5]] ] 1425 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[DOTPN]] 1426 // CHECK-EH-03: terminate.lpad: 1427 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 1428 // CHECK-EH-03-NEXT: catch i8* null 1429 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 1430 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR8]] 1431 // CHECK-EH-03-NEXT: unreachable 1432 // 1433 // CHECK-EH-11-LABEL: @_Z6test18i( 1434 // CHECK-EH-11-NEXT: entry: 1435 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1436 // CHECK-EH-11-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 1437 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1438 // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], 0 1439 // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 1440 // CHECK-EH-11: nrvo.unused: 1441 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 1442 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1443 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1444 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1445 // CHECK-EH-11-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I]], 1 1446 // CHECK-EH-11-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[CLEANUP_CONT7_CRITEDGE:%.*]] 1447 // CHECK-EH-11: if.then2: 1448 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1449 // CHECK-EH-11-NEXT: to label [[CLEANUP4:%.*]] unwind label [[LPAD:%.*]] 1450 // CHECK-EH-11: lpad: 1451 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1452 // CHECK-EH-11-NEXT: cleanup 1453 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1454 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1455 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 1456 // CHECK-EH-11: cleanup4: 1457 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1458 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1459 // CHECK-EH-11-NEXT: br i1 [[CMP1]], label [[RETURN]], label [[CLEANUP_CONT7:%.*]] 1460 // CHECK-EH-11: cleanup.cont7.critedge: 1461 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1462 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1463 // CHECK-EH-11-NEXT: br label [[CLEANUP_CONT7]] 1464 // CHECK-EH-11: cleanup.cont7: 1465 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Z]], i32 0, i32 0 1466 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1467 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1468 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 1469 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]] 1470 // CHECK-EH-11: invoke.cont9: 1471 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR7]] 1472 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1473 // CHECK-EH-11-NEXT: br label [[RETURN]] 1474 // CHECK-EH-11: lpad8: 1475 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1476 // CHECK-EH-11-NEXT: cleanup 1477 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) #[[ATTR7]] 1478 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]] 1479 // CHECK-EH-11-NEXT: br label [[EH_RESUME]] 1480 // CHECK-EH-11: return: 1481 // CHECK-EH-11-NEXT: ret void 1482 // CHECK-EH-11: eh.resume: 1483 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD8]] ], [ [[TMP1]], [[LPAD]] ] 1484 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN]] 1485 // 1486 X test18(int i) { // http://wg21.link/p2025r2#ex-11 1487 { 1488 { 1489 X x; 1490 if (i == 0) 1491 return x; // NRVO happens 1492 } 1493 X y; 1494 if (i == 1) 1495 return y; // FIXME: NRVO could happen, but doesn't 1496 } 1497 X z; 1498 return z; // FIXME: NRVO could happen, but doesn't 1499 } 1500 1501 #ifdef CXX11 1502 // CHECK-EH-11-LABEL: @_Z6test19v( 1503 // CHECK-EH-11-NEXT: entry: 1504 // CHECK-EH-11-NEXT: [[L:%.*]] = alloca [[CLASS_X:%.*]], align 1 1505 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1506 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[L]], i32 0, i32 0 1507 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1508 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[L]]) 1509 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1510 // CHECK-EH-11: invoke.cont: 1511 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[L]]) #[[ATTR7]] 1512 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1513 // CHECK-EH-11-NEXT: ret void 1514 // CHECK-EH-11: lpad: 1515 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1516 // CHECK-EH-11-NEXT: cleanup 1517 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1518 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 1519 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 1520 // 1521 X test19() { // http://wg21.link/p2025r2#ex-12 1522 X x; 1523 struct S { 1524 X f() { return X(); } 1525 }; 1526 auto L = [&x]() { return X(); }(); 1527 if constexpr (false) { 1528 return X(); 1529 } 1530 return x; // NRVO happens 1531 } 1532 1533 template <bool B> 1534 X test20() { // http://wg21.link/p2025r2#ex-18 1535 X x; 1536 if constexpr (B) { 1537 if (false) 1538 return X(); 1539 } 1540 return x; // FIXME: NRVO could happen when B == false, but doesn't 1541 } 1542 1543 // CHECK-EH-11-LABEL: @_Z17test20instantiatev( 1544 // CHECK-EH-11-NEXT: entry: 1545 // CHECK-EH-11-NEXT: [[X_I2:%.*]] = alloca [[CLASS_X:%.*]], align 1 1546 // CHECK-EH-11-NEXT: [[X_I:%.*]] = alloca [[CLASS_X]], align 1 1547 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X]], align 1 1548 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 1549 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I]], i32 0, i32 0 1550 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6 1551 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]), !noalias !6 1552 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) 1553 // CHECK-EH-11-NEXT: to label [[_Z6TEST20ILB1EE1XV_EXIT:%.*]] unwind label [[LPAD_I:%.*]] 1554 // CHECK-EH-11: common.resume: 1555 // CHECK-EH-11-NEXT: [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[TMP1:%.*]], [[LPAD_I]] ], [ [[TMP3:%.*]], [[LPAD_I3:%.*]] ] 1556 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[COMMON_RESUME_OP]] 1557 // CHECK-EH-11: lpad.i: 1558 // CHECK-EH-11-NEXT: [[TMP1]] = landingpad { i8*, i32 } 1559 // CHECK-EH-11-NEXT: cleanup 1560 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]] 1561 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6 1562 // CHECK-EH-11-NEXT: br label [[COMMON_RESUME:%.*]] 1563 // CHECK-EH-11: _Z6test20ILb1EE1Xv.exit: 1564 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]] 1565 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !6 1566 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR7]] 1567 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I2]], i32 0, i32 0 1568 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9 1569 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]), !noalias !9 1570 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) 1571 // CHECK-EH-11-NEXT: to label [[_Z6TEST20ILB0EE1XV_EXIT:%.*]] unwind label [[LPAD_I3]] 1572 // CHECK-EH-11: lpad.i3: 1573 // CHECK-EH-11-NEXT: [[TMP3]] = landingpad { i8*, i32 } 1574 // CHECK-EH-11-NEXT: cleanup 1575 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]] 1576 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9 1577 // CHECK-EH-11-NEXT: br label [[COMMON_RESUME]] 1578 // CHECK-EH-11: _Z6test20ILb0EE1Xv.exit: 1579 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]] 1580 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !9 1581 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR7]] 1582 // CHECK-EH-11-NEXT: ret void 1583 // 1584 void test20instantiate() { 1585 test20<true>(); 1586 test20<false>(); 1587 } 1588 #endif 1589 1590 // CHECK-LABEL: @_Z6test21v( 1591 // CHECK-NEXT: entry: 1592 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 1593 // CHECK-NEXT: ret void 1594 // 1595 // CHECK-EH-LABEL: @_Z6test21v( 1596 // CHECK-EH-NEXT: entry: 1597 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1598 // CHECK-EH-NEXT: ret void 1599 // 1600 const volatile X test21() { // http://wg21.link/p2025r2#ex-19 1601 X x; 1602 return x; // NRVO happens 1603 } 1604 1605 // CHECK-LABEL: @_Z6test22v( 1606 // CHECK-NEXT: entry: 1607 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1608 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1609 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1610 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 1611 // CHECK-NEXT: call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 1612 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 1613 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1614 // CHECK-NEXT: ret void 1615 // 1616 // CHECK-EH-03-LABEL: @_Z6test22v( 1617 // CHECK-EH-03-NEXT: entry: 1618 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1619 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1620 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1621 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1622 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1623 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1624 // CHECK-EH-03: invoke.cont: 1625 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1626 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1627 // CHECK-EH-03-NEXT: ret void 1628 // CHECK-EH-03: lpad: 1629 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1630 // CHECK-EH-03-NEXT: cleanup 1631 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1632 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1633 // CHECK-EH-03: invoke.cont1: 1634 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1635 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 1636 // CHECK-EH-03: terminate.lpad: 1637 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 1638 // CHECK-EH-03-NEXT: catch i8* null 1639 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 1640 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 1641 // CHECK-EH-03-NEXT: unreachable 1642 // 1643 // CHECK-EH-11-LABEL: @_Z6test22v( 1644 // CHECK-EH-11-NEXT: entry: 1645 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1646 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 1647 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1648 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1649 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1650 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1651 // CHECK-EH-11: invoke.cont: 1652 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1653 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1654 // CHECK-EH-11-NEXT: ret void 1655 // CHECK-EH-11: lpad: 1656 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1657 // CHECK-EH-11-NEXT: cleanup 1658 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 1659 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1660 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 1661 // 1662 X test22() { // http://wg21.link/p2025r2#ex-19 1663 volatile X x; 1664 return x; // NRVO is impossible 1665 } 1666 1667 // CHECK-LABEL: @_Z6test23b( 1668 // CHECK-NEXT: entry: 1669 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1670 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1671 // CHECK: if.then: 1672 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 1673 // CHECK-NEXT: br label [[RETURN:%.*]] 1674 // CHECK: if.end: 1675 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1676 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1677 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1678 // CHECK-NEXT: call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1679 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 1680 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 1681 // CHECK-NEXT: br label [[RETURN]] 1682 // CHECK: return: 1683 // CHECK-NEXT: ret void 1684 // 1685 // CHECK-EH-03-LABEL: @_Z6test23b( 1686 // CHECK-EH-03-NEXT: entry: 1687 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1688 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1689 // CHECK-EH-03: if.then: 1690 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1691 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 1692 // CHECK-EH-03: if.end: 1693 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1694 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1695 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1696 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1697 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1698 // CHECK-EH-03: invoke.cont: 1699 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1700 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1701 // CHECK-EH-03-NEXT: br label [[RETURN]] 1702 // CHECK-EH-03: lpad: 1703 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1704 // CHECK-EH-03-NEXT: cleanup 1705 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1706 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1707 // CHECK-EH-03: invoke.cont1: 1708 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1709 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 1710 // CHECK-EH-03: return: 1711 // CHECK-EH-03-NEXT: ret void 1712 // CHECK-EH-03: terminate.lpad: 1713 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 1714 // CHECK-EH-03-NEXT: catch i8* null 1715 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 1716 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 1717 // CHECK-EH-03-NEXT: unreachable 1718 // 1719 // CHECK-EH-11-LABEL: @_Z6test23b( 1720 // CHECK-EH-11-NEXT: entry: 1721 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 1722 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1723 // CHECK-EH-11: if.then: 1724 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1725 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 1726 // CHECK-EH-11: if.end: 1727 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 1728 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1729 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1730 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1731 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1732 // CHECK-EH-11: invoke.cont: 1733 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1734 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1735 // CHECK-EH-11-NEXT: br label [[RETURN]] 1736 // CHECK-EH-11: lpad: 1737 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 1738 // CHECK-EH-11-NEXT: cleanup 1739 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 1740 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 1741 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 1742 // CHECK-EH-11: return: 1743 // CHECK-EH-11-NEXT: ret void 1744 // 1745 X test23(bool b) { // http://wg21.link/p2025r2#ex-19 1746 if (b) { 1747 const X x; 1748 return x; // NRVO happens 1749 } 1750 volatile X y; 1751 return y; // NRVO is impossible 1752 } 1753 1754 #ifdef __EXCEPTIONS 1755 // CHECK-EH-LABEL: @_Z6test24v( 1756 // CHECK-EH-NEXT: entry: 1757 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 1758 // CHECK-EH-NEXT: ret void 1759 // 1760 X test24() { // http://wg21.link/p2025r2#ex-20 1761 X x; 1762 if (&x == &OuterX) 1763 throw 0; 1764 return x; // NRVO happens 1765 } 1766 #endif 1767 1768 #ifdef CXX11 1769 template <bool B> 1770 X test25() { 1771 X x; 1772 if constexpr (B) { 1773 return x; // FIXME: NRVO could happen when B == true, but doesn't 1774 } else { 1775 return X(); 1776 } 1777 } 1778 1779 // CHECK-EH-11-LABEL: @_Z17test25instantiatev( 1780 // CHECK-EH-11-NEXT: entry: 1781 // CHECK-EH-11-NEXT: [[X_I2:%.*]] = alloca [[CLASS_X:%.*]], align 1 1782 // CHECK-EH-11-NEXT: [[X_I:%.*]] = alloca [[CLASS_X]], align 1 1783 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X]], align 1 1784 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 1785 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I]], i32 0, i32 0 1786 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12 1787 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]), !noalias !12 1788 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) 1789 // CHECK-EH-11-NEXT: to label [[_Z6TEST25ILB1EE1XV_EXIT:%.*]] unwind label [[LPAD_I:%.*]] 1790 // CHECK-EH-11: common.resume: 1791 // CHECK-EH-11-NEXT: [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[TMP1:%.*]], [[LPAD_I]] ], [ [[TMP3:%.*]], [[LPAD_I3:%.*]] ] 1792 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[COMMON_RESUME_OP]] 1793 // CHECK-EH-11: lpad.i: 1794 // CHECK-EH-11-NEXT: [[TMP1]] = landingpad { i8*, i32 } 1795 // CHECK-EH-11-NEXT: cleanup 1796 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]] 1797 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12 1798 // CHECK-EH-11-NEXT: br label [[COMMON_RESUME:%.*]] 1799 // CHECK-EH-11: _Z6test25ILb1EE1Xv.exit: 1800 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I]]) #[[ATTR7]] 1801 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]], !noalias !12 1802 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR7]] 1803 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X_I2]], i32 0, i32 0 1804 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15 1805 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]), !noalias !15 1806 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) 1807 // CHECK-EH-11-NEXT: to label [[_Z6TEST25ILB0EE1XV_EXIT:%.*]] unwind label [[LPAD_I3]] 1808 // CHECK-EH-11: lpad.i3: 1809 // CHECK-EH-11-NEXT: [[TMP3]] = landingpad { i8*, i32 } 1810 // CHECK-EH-11-NEXT: cleanup 1811 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]] 1812 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15 1813 // CHECK-EH-11-NEXT: br label [[COMMON_RESUME]] 1814 // CHECK-EH-11: _Z6test25ILb0EE1Xv.exit: 1815 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X_I2]]) #[[ATTR7]] 1816 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP2]]) #[[ATTR7]], !noalias !15 1817 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR7]] 1818 // CHECK-EH-11-NEXT: ret void 1819 // 1820 void test25instantiate() { 1821 test25<true>(); 1822 test25<false>(); 1823 } 1824 #endif 1825