1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -no-opaque-pointers -triple i386-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s 3 // RUN: %clang_cc1 -no-opaque-pointers -triple i386-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH-03 %s 4 // RUN: %clang_cc1 -no-opaque-pointers -triple i386-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions -disable-llvm-passes -std=c++11 -DCXX11 -o - %s | FileCheck --check-prefixes=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: [[RESULT_PTR:%.*]] = alloca i8*, align 4 29 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 30 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 31 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 32 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 33 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 34 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 35 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 36 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 37 // CHECK: nrvo.unused: 38 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 39 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 40 // CHECK: nrvo.skipdtor: 41 // CHECK-NEXT: ret void 42 // 43 // CHECK-EH-03-LABEL: @_Z5test0v( 44 // CHECK-EH-03-NEXT: entry: 45 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 46 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 47 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 48 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 49 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 50 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 51 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 52 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 53 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 54 // CHECK-EH-03: nrvo.unused: 55 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 56 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 57 // CHECK-EH-03: nrvo.skipdtor: 58 // CHECK-EH-03-NEXT: ret void 59 // 60 // CHECK-EH-11-LABEL: @_Z5test0v( 61 // CHECK-EH-11-NEXT: entry: 62 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 63 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 64 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 65 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 66 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 67 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 68 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 69 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 70 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 71 // CHECK-EH-11: nrvo.unused: 72 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 73 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 74 // CHECK-EH-11: nrvo.skipdtor: 75 // CHECK-EH-11-NEXT: ret void 76 // 77 X test0() { // http://wg21.link/p2025r2#ex-2 78 X x; 79 return x; // NRVO happens 80 } 81 82 // CHECK-LABEL: @_Z5test1b( 83 // CHECK-NEXT: entry: 84 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 85 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 86 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 87 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 88 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 89 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 90 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 91 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 92 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 93 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 94 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 95 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 96 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 97 // CHECK: if.then: 98 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 99 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 100 // CHECK-NEXT: br label [[CLEANUP:%.*]] 101 // CHECK: if.end: 102 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 103 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 104 // CHECK-NEXT: br label [[CLEANUP]] 105 // CHECK: cleanup: 106 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 107 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 108 // CHECK: nrvo.unused: 109 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 110 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 111 // CHECK: nrvo.skipdtor: 112 // CHECK-NEXT: ret void 113 // 114 // CHECK-EH-03-LABEL: @_Z5test1b( 115 // CHECK-EH-03-NEXT: entry: 116 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 117 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 118 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 119 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 120 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 121 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 122 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 123 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 124 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 125 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 126 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 127 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 128 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 129 // CHECK-EH-03: if.then: 130 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 131 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 132 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 133 // CHECK-EH-03: if.end: 134 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 135 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 136 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 137 // CHECK-EH-03: cleanup: 138 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 139 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 140 // CHECK-EH-03: nrvo.unused: 141 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 142 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 143 // CHECK-EH-03: nrvo.skipdtor: 144 // CHECK-EH-03-NEXT: ret void 145 // 146 // CHECK-EH-11-LABEL: @_Z5test1b( 147 // CHECK-EH-11-NEXT: entry: 148 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 149 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 150 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 151 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 152 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 153 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 154 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 155 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 156 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 157 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 158 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 159 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 160 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 161 // CHECK-EH-11: if.then: 162 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 163 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 164 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 165 // CHECK-EH-11: if.end: 166 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 167 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 168 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 169 // CHECK-EH-11: cleanup: 170 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 171 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 172 // CHECK-EH-11: nrvo.unused: 173 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 174 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 175 // CHECK-EH-11: nrvo.skipdtor: 176 // CHECK-EH-11-NEXT: ret void 177 // 178 X test1(bool B) { 179 X x; 180 if (B) 181 return (x); // NRVO happens 182 return x; // NRVO happens 183 } 184 185 // CHECK-LABEL: @_Z5test2b( 186 // CHECK-NEXT: entry: 187 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 188 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 189 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 190 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 191 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 192 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 193 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 194 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 195 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 196 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 197 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 198 // CHECK-NEXT: [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1 199 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1 200 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 201 // CHECK: if.then: 202 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 203 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 204 // CHECK-NEXT: br label [[CLEANUP:%.*]] 205 // CHECK: if.end: 206 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 207 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 208 // CHECK-NEXT: br label [[CLEANUP]] 209 // CHECK: cleanup: 210 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 211 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 212 // CHECK-NEXT: ret void 213 // 214 // CHECK-EH-03-LABEL: @_Z5test2b( 215 // CHECK-EH-03-NEXT: entry: 216 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 217 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 218 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 219 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 220 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 221 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 222 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 223 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 224 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 225 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 226 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 227 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 228 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 229 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 230 // CHECK-EH-03: invoke.cont: 231 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1 232 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1 233 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 234 // CHECK-EH-03: if.then: 235 // 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]]) 236 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 237 // CHECK-EH-03: invoke.cont2: 238 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 239 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 240 // CHECK-EH-03: lpad: 241 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 242 // CHECK-EH-03-NEXT: cleanup 243 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 244 // CHECK-EH-03-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 245 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 246 // CHECK-EH-03-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 247 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 248 // CHECK-EH-03: lpad1: 249 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } 250 // CHECK-EH-03-NEXT: cleanup 251 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 252 // CHECK-EH-03-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4 253 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 254 // CHECK-EH-03-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 255 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 256 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 257 // CHECK-EH-03: if.end: 258 // 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]]) 259 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] 260 // CHECK-EH-03: invoke.cont3: 261 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 262 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 263 // CHECK-EH-03: cleanup: 264 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 265 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] 266 // CHECK-EH-03: invoke.cont4: 267 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 268 // CHECK-EH-03-NEXT: ret void 269 // CHECK-EH-03: invoke.cont5: 270 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 271 // CHECK-EH-03: ehcleanup: 272 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 273 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[TERMINATE_LPAD]] 274 // CHECK-EH-03: invoke.cont7: 275 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 276 // CHECK-EH-03: eh.resume: 277 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 278 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 279 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 280 // CHECK-EH-03-NEXT: [[LPAD_VAL12:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 281 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL12]] 282 // CHECK-EH-03: terminate.lpad: 283 // CHECK-EH-03-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } 284 // CHECK-EH-03-NEXT: catch i8* null 285 // CHECK-EH-03-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 286 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) 287 // CHECK-EH-03-NEXT: unreachable 288 // 289 // CHECK-EH-11-LABEL: @_Z5test2b( 290 // CHECK-EH-11-NEXT: entry: 291 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 292 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 293 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 294 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 295 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 296 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 297 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 298 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 299 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 300 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 301 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 302 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 303 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 304 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 305 // CHECK-EH-11: invoke.cont: 306 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = load i8, i8* [[B_ADDR]], align 1 307 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP3]] to i1 308 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 309 // CHECK-EH-11: if.then: 310 // 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]]) 311 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 312 // CHECK-EH-11: invoke.cont2: 313 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 314 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 315 // CHECK-EH-11: lpad: 316 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 317 // CHECK-EH-11-NEXT: cleanup 318 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 319 // CHECK-EH-11-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 320 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 321 // CHECK-EH-11-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 322 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 323 // CHECK-EH-11: lpad1: 324 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } 325 // CHECK-EH-11-NEXT: cleanup 326 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 327 // CHECK-EH-11-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4 328 // CHECK-EH-11-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 329 // CHECK-EH-11-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 330 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 331 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 332 // CHECK-EH-11: if.end: 333 // 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]]) 334 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] 335 // CHECK-EH-11: invoke.cont3: 336 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 337 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 338 // CHECK-EH-11: cleanup: 339 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 340 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 341 // CHECK-EH-11-NEXT: ret void 342 // CHECK-EH-11: ehcleanup: 343 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 344 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 345 // CHECK-EH-11: eh.resume: 346 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 347 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 348 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 349 // CHECK-EH-11-NEXT: [[LPAD_VAL9:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 350 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL9]] 351 // 352 X test2(bool B) { 353 X x; 354 X y; 355 if (B) 356 return y; // NRVO is impossible 357 return x; // NRVO is impossible 358 } 359 360 // CHECK-LABEL: @_Z5test3b( 361 // CHECK-NEXT: entry: 362 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 363 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 364 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 365 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 366 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 367 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 368 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 369 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 370 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 371 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 372 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 373 // CHECK: if.then: 374 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 375 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 376 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 377 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 378 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 379 // CHECK: nrvo.unused: 380 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 381 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 382 // CHECK: nrvo.skipdtor: 383 // CHECK-NEXT: br label [[RETURN:%.*]] 384 // CHECK: if.end: 385 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 386 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 387 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 388 // CHECK-NEXT: br label [[RETURN]] 389 // CHECK: return: 390 // CHECK-NEXT: ret void 391 // 392 // CHECK-EH-03-LABEL: @_Z5test3b( 393 // CHECK-EH-03-NEXT: entry: 394 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 395 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 396 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 397 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 398 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 399 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 400 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 401 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 402 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 403 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 404 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 405 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 406 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 407 // CHECK-EH-03: if.then: 408 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 409 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 410 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 411 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 412 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 413 // CHECK-EH-03: nrvo.unused: 414 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 415 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 416 // CHECK-EH-03: nrvo.skipdtor: 417 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 418 // CHECK-EH-03: if.end: 419 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 420 // 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]]) 421 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 422 // CHECK-EH-03: invoke.cont: 423 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 424 // CHECK-EH-03-NEXT: br label [[RETURN]] 425 // CHECK-EH-03: lpad: 426 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 427 // CHECK-EH-03-NEXT: cleanup 428 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 429 // CHECK-EH-03-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 430 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 431 // CHECK-EH-03-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 432 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 433 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 434 // CHECK-EH-03: invoke.cont1: 435 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 436 // CHECK-EH-03: return: 437 // CHECK-EH-03-NEXT: ret void 438 // CHECK-EH-03: eh.resume: 439 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 440 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 441 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 442 // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 443 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL2]] 444 // CHECK-EH-03: terminate.lpad: 445 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 446 // CHECK-EH-03-NEXT: catch i8* null 447 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 448 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP9]]) 449 // CHECK-EH-03-NEXT: unreachable 450 // 451 // CHECK-EH-11-LABEL: @_Z5test3b( 452 // CHECK-EH-11-NEXT: entry: 453 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 454 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 455 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 456 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 457 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 458 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 459 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 460 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 461 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 462 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 463 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 464 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 465 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 466 // CHECK-EH-11: if.then: 467 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 468 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 469 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 470 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 471 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 472 // CHECK-EH-11: nrvo.unused: 473 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 474 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 475 // CHECK-EH-11: nrvo.skipdtor: 476 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 477 // CHECK-EH-11: if.end: 478 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 479 // 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]]) 480 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 481 // CHECK-EH-11: invoke.cont: 482 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 483 // CHECK-EH-11-NEXT: br label [[RETURN]] 484 // CHECK-EH-11: lpad: 485 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 486 // CHECK-EH-11-NEXT: cleanup 487 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 488 // CHECK-EH-11-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 489 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 490 // CHECK-EH-11-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 491 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 492 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 493 // CHECK-EH-11: return: 494 // CHECK-EH-11-NEXT: ret void 495 // CHECK-EH-11: eh.resume: 496 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 497 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 498 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 499 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 500 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 501 // 502 X test3(bool B) { // http://wg21.link/p2025r2#ex-4 503 if (B) { 504 X y; 505 return y; // NRVO happens 506 } 507 X x; 508 return x; // FIXME: NRVO could happen, but doesn't 509 } 510 511 extern "C" void exit(int) throw(); 512 513 // CHECK-LABEL: @_Z5test4b( 514 // CHECK-NEXT: entry: 515 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 516 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 517 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 518 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 519 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 520 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 521 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 522 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 523 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 524 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 525 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 526 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 527 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 528 // CHECK: if.then: 529 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 530 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 531 // CHECK-NEXT: br label [[CLEANUP:%.*]] 532 // CHECK: if.end: 533 // CHECK-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 534 // CHECK-NEXT: br label [[CLEANUP]] 535 // CHECK: cleanup: 536 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 537 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 538 // CHECK: nrvo.unused: 539 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 540 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 541 // CHECK: nrvo.skipdtor: 542 // CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 543 // CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 544 // CHECK-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 545 // CHECK-NEXT: i32 1, label [[RETURN:%.*]] 546 // CHECK-NEXT: ] 547 // CHECK: cleanup.cont: 548 // CHECK-NEXT: call void @exit(i32 noundef 1) 549 // CHECK-NEXT: call void @llvm.trap() 550 // CHECK-NEXT: unreachable 551 // CHECK: return: 552 // CHECK-NEXT: ret void 553 // CHECK: unreachable: 554 // CHECK-NEXT: unreachable 555 // 556 // CHECK-EH-03-LABEL: @_Z5test4b( 557 // CHECK-EH-03-NEXT: entry: 558 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 559 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 560 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 561 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 562 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 563 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 564 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 565 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 566 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 567 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 568 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 569 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 570 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 571 // CHECK-EH-03: if.then: 572 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 573 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 574 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 575 // CHECK-EH-03: if.end: 576 // CHECK-EH-03-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 577 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 578 // CHECK-EH-03: cleanup: 579 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 580 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 581 // CHECK-EH-03: nrvo.unused: 582 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 583 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 584 // CHECK-EH-03: nrvo.skipdtor: 585 // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 586 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 587 // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 588 // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] 589 // CHECK-EH-03-NEXT: ] 590 // CHECK-EH-03: cleanup.cont: 591 // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) 592 // CHECK-EH-03-NEXT: call void @llvm.trap() 593 // CHECK-EH-03-NEXT: unreachable 594 // CHECK-EH-03: return: 595 // CHECK-EH-03-NEXT: ret void 596 // CHECK-EH-03: unreachable: 597 // CHECK-EH-03-NEXT: unreachable 598 // 599 // CHECK-EH-11-LABEL: @_Z5test4b( 600 // CHECK-EH-11-NEXT: entry: 601 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 602 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 603 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 604 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 605 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 606 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 607 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 608 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 609 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 610 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 611 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 612 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 613 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 614 // CHECK-EH-11: if.then: 615 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 616 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 617 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 618 // CHECK-EH-11: if.end: 619 // CHECK-EH-11-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 620 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 621 // CHECK-EH-11: cleanup: 622 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 623 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 624 // CHECK-EH-11: nrvo.unused: 625 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 626 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 627 // CHECK-EH-11: nrvo.skipdtor: 628 // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 629 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 630 // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 631 // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] 632 // CHECK-EH-11-NEXT: ] 633 // CHECK-EH-11: cleanup.cont: 634 // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) 635 // CHECK-EH-11-NEXT: call void @llvm.trap() 636 // CHECK-EH-11-NEXT: unreachable 637 // CHECK-EH-11: return: 638 // CHECK-EH-11-NEXT: ret void 639 // CHECK-EH-11: unreachable: 640 // CHECK-EH-11-NEXT: unreachable 641 // 642 X test4(bool B) { 643 { 644 X x; 645 if (B) 646 return x; // NRVO happens 647 } 648 exit(1); 649 } 650 651 #ifdef __EXCEPTIONS 652 void may_throw(); 653 // CHECK-EH-03-LABEL: @_Z5test5v( 654 // CHECK-EH-03-NEXT: entry: 655 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 656 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 657 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 658 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 659 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 660 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 661 // CHECK-EH-03-NEXT: invoke void @_Z9may_throwv() 662 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 663 // CHECK-EH-03: invoke.cont: 664 // CHECK-EH-03-NEXT: br label [[TRY_CONT:%.*]] 665 // CHECK-EH-03: lpad: 666 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 667 // CHECK-EH-03-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 668 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0 669 // CHECK-EH-03-NEXT: store i8* [[TMP2]], i8** [[EXN_SLOT]], align 4 670 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1 671 // CHECK-EH-03-NEXT: store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4 672 // CHECK-EH-03-NEXT: br label [[CATCH_DISPATCH:%.*]] 673 // CHECK-EH-03: catch.dispatch: 674 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 675 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) 676 // CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]] 677 // CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 678 // CHECK-EH-03: catch: 679 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 680 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) 681 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %class.X* 682 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP7]]) 683 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 684 // CHECK-EH-03: invoke.cont1: 685 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) 686 // 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]]) 687 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 688 // CHECK-EH-03: invoke.cont3: 689 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 690 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]] 691 // CHECK-EH-03: lpad2: 692 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } 693 // CHECK-EH-03-NEXT: cleanup 694 // CHECK-EH-03-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 695 // CHECK-EH-03-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 4 696 // CHECK-EH-03-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1 697 // CHECK-EH-03-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4 698 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 699 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD]] 700 // CHECK-EH-03: invoke.cont5: 701 // CHECK-EH-03-NEXT: call void @__cxa_end_catch() 702 // CHECK-EH-03-NEXT: ret void 703 // CHECK-EH-03: lpad4: 704 // CHECK-EH-03-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } 705 // CHECK-EH-03-NEXT: cleanup 706 // CHECK-EH-03-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0 707 // CHECK-EH-03-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 4 708 // CHECK-EH-03-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1 709 // CHECK-EH-03-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4 710 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 711 // CHECK-EH-03: invoke.cont6: 712 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 713 // CHECK-EH-03: ehcleanup: 714 // CHECK-EH-03-NEXT: invoke void @__cxa_end_catch() 715 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]] 716 // CHECK-EH-03: invoke.cont7: 717 // CHECK-EH-03-NEXT: br label [[EH_RESUME]] 718 // CHECK-EH-03: try.cont: 719 // CHECK-EH-03-NEXT: call void @llvm.trap() 720 // CHECK-EH-03-NEXT: unreachable 721 // CHECK-EH-03: eh.resume: 722 // CHECK-EH-03-NEXT: [[EXN9:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 723 // CHECK-EH-03-NEXT: [[SEL10:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 724 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN9]], 0 725 // CHECK-EH-03-NEXT: [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL10]], 1 726 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL11]] 727 // CHECK-EH-03: terminate.lpad: 728 // CHECK-EH-03-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } 729 // CHECK-EH-03-NEXT: catch i8* null 730 // CHECK-EH-03-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 731 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) 732 // CHECK-EH-03-NEXT: unreachable 733 // 734 // CHECK-EH-11-LABEL: @_Z5test5v( 735 // CHECK-EH-11-NEXT: entry: 736 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 737 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 738 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 739 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 740 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 741 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 742 // CHECK-EH-11-NEXT: invoke void @_Z9may_throwv() 743 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 744 // CHECK-EH-11: invoke.cont: 745 // CHECK-EH-11-NEXT: br label [[TRY_CONT:%.*]] 746 // CHECK-EH-11: lpad: 747 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 748 // CHECK-EH-11-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 749 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0 750 // CHECK-EH-11-NEXT: store i8* [[TMP2]], i8** [[EXN_SLOT]], align 4 751 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1 752 // CHECK-EH-11-NEXT: store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4 753 // CHECK-EH-11-NEXT: br label [[CATCH_DISPATCH:%.*]] 754 // CHECK-EH-11: catch.dispatch: 755 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 756 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) 757 // CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]] 758 // CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 759 // CHECK-EH-11: catch: 760 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 761 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) 762 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = bitcast i8* [[TMP6]] to %class.X* 763 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP7]]) 764 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 765 // CHECK-EH-11: invoke.cont1: 766 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) 767 // 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]]) 768 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 769 // CHECK-EH-11: invoke.cont3: 770 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 771 // CHECK-EH-11-NEXT: call void @__cxa_end_catch() 772 // CHECK-EH-11-NEXT: ret void 773 // CHECK-EH-11: lpad2: 774 // CHECK-EH-11-NEXT: [[TMP10:%.*]] = landingpad { i8*, i32 } 775 // CHECK-EH-11-NEXT: cleanup 776 // CHECK-EH-11-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0 777 // CHECK-EH-11-NEXT: store i8* [[TMP11]], i8** [[EXN_SLOT]], align 4 778 // CHECK-EH-11-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 1 779 // CHECK-EH-11-NEXT: store i32 [[TMP12]], i32* [[EHSELECTOR_SLOT]], align 4 780 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 781 // CHECK-EH-11-NEXT: invoke void @__cxa_end_catch() 782 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]] 783 // CHECK-EH-11: invoke.cont4: 784 // CHECK-EH-11-NEXT: br label [[EH_RESUME]] 785 // CHECK-EH-11: try.cont: 786 // CHECK-EH-11-NEXT: call void @llvm.trap() 787 // CHECK-EH-11-NEXT: unreachable 788 // CHECK-EH-11: eh.resume: 789 // CHECK-EH-11-NEXT: [[EXN5:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 790 // CHECK-EH-11-NEXT: [[SEL6:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 791 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN5]], 0 792 // CHECK-EH-11-NEXT: [[LPAD_VAL7:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL6]], 1 793 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL7]] 794 // CHECK-EH-11: terminate.lpad: 795 // CHECK-EH-11-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } 796 // CHECK-EH-11-NEXT: catch i8* null 797 // CHECK-EH-11-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 798 // CHECK-EH-11-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) 799 // CHECK-EH-11-NEXT: unreachable 800 // 801 X test5() { // http://wg21.link/p2025r2#ex-14 802 try { 803 may_throw(); 804 } catch (X x) { 805 return x; // FIXME: NRVO could happen, but doesn't 806 } 807 } 808 #endif 809 810 // rdar://problem/10430868 811 // CHECK-LABEL: @_Z5test6v( 812 // CHECK-NEXT: entry: 813 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 814 // CHECK-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 815 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 816 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 817 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 818 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 819 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 820 // CHECK-NEXT: ret void 821 // 822 // CHECK-EH-03-LABEL: @_Z5test6v( 823 // CHECK-EH-03-NEXT: entry: 824 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 825 // CHECK-EH-03-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 826 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 827 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 828 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 829 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 830 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 831 // 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]]) 832 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 833 // CHECK-EH-03: invoke.cont: 834 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 835 // CHECK-EH-03-NEXT: ret void 836 // CHECK-EH-03: lpad: 837 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 838 // CHECK-EH-03-NEXT: cleanup 839 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 840 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 841 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 842 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 843 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 844 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 845 // CHECK-EH-03: invoke.cont1: 846 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 847 // CHECK-EH-03: eh.resume: 848 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 849 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 850 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 851 // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 852 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL2]] 853 // CHECK-EH-03: terminate.lpad: 854 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } 855 // CHECK-EH-03-NEXT: catch i8* null 856 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 857 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP8]]) 858 // CHECK-EH-03-NEXT: unreachable 859 // 860 // CHECK-EH-11-LABEL: @_Z5test6v( 861 // CHECK-EH-11-NEXT: entry: 862 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 863 // CHECK-EH-11-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 864 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 865 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 866 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 867 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 868 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 869 // 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]]) 870 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 871 // CHECK-EH-11: invoke.cont: 872 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 873 // CHECK-EH-11-NEXT: ret void 874 // CHECK-EH-11: lpad: 875 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 876 // CHECK-EH-11-NEXT: cleanup 877 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 878 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 879 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 880 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 881 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 882 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 883 // CHECK-EH-11: eh.resume: 884 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 885 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 886 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 887 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 888 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 889 // 890 X test6() { 891 X a __attribute__((aligned(8))); 892 return a; // NRVO is impossible 893 } 894 895 // CHECK-LABEL: @_Z5test7b( 896 // CHECK-NEXT: entry: 897 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 898 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 899 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 900 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 901 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 902 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 903 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 904 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 905 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 906 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 907 // CHECK: if.then: 908 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 909 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 910 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 911 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 912 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 913 // CHECK: nrvo.unused: 914 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 915 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 916 // CHECK: nrvo.skipdtor: 917 // CHECK-NEXT: br label [[RETURN:%.*]] 918 // CHECK: if.end: 919 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 920 // CHECK-NEXT: br label [[RETURN]] 921 // CHECK: return: 922 // CHECK-NEXT: ret void 923 // 924 // CHECK-EH-03-LABEL: @_Z5test7b( 925 // CHECK-EH-03-NEXT: entry: 926 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 927 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 928 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 929 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 930 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 931 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 932 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 933 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 934 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 935 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 936 // CHECK-EH-03: if.then: 937 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 938 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 939 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 940 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 941 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 942 // CHECK-EH-03: nrvo.unused: 943 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 944 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 945 // CHECK-EH-03: nrvo.skipdtor: 946 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 947 // CHECK-EH-03: if.end: 948 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 949 // CHECK-EH-03-NEXT: br label [[RETURN]] 950 // CHECK-EH-03: return: 951 // CHECK-EH-03-NEXT: ret void 952 // 953 // CHECK-EH-11-LABEL: @_Z5test7b( 954 // CHECK-EH-11-NEXT: entry: 955 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 956 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 957 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 958 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 959 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 960 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 961 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 962 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 963 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 964 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 965 // CHECK-EH-11: if.then: 966 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 967 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 968 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 969 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 970 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 971 // CHECK-EH-11: nrvo.unused: 972 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 973 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 974 // CHECK-EH-11: nrvo.skipdtor: 975 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 976 // CHECK-EH-11: if.end: 977 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 978 // CHECK-EH-11-NEXT: br label [[RETURN]] 979 // CHECK-EH-11: return: 980 // CHECK-EH-11-NEXT: ret void 981 // 982 X test7(bool b) { 983 if (b) { 984 X x; 985 return x; // NRVO happens 986 } 987 return X(); 988 } 989 990 // CHECK-LABEL: @_Z5test8b( 991 // CHECK-NEXT: entry: 992 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 993 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 994 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 995 // CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 996 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 997 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 998 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 999 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1000 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1001 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1002 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1003 // CHECK: if.then: 1004 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 1005 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1006 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 1007 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1008 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1009 // CHECK: nrvo.unused: 1010 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1011 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 1012 // CHECK: nrvo.skipdtor: 1013 // CHECK-NEXT: br label [[RETURN:%.*]] 1014 // CHECK: if.else: 1015 // CHECK-NEXT: store i1 false, i1* [[NRVO1]], align 1 1016 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1017 // CHECK-NEXT: store i1 true, i1* [[NRVO1]], align 1 1018 // CHECK-NEXT: [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1 1019 // CHECK-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] 1020 // CHECK: nrvo.unused3: 1021 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1022 // CHECK-NEXT: br label [[NRVO_SKIPDTOR4]] 1023 // CHECK: nrvo.skipdtor4: 1024 // CHECK-NEXT: br label [[RETURN]] 1025 // CHECK: return: 1026 // CHECK-NEXT: ret void 1027 // 1028 // CHECK-EH-03-LABEL: @_Z5test8b( 1029 // CHECK-EH-03-NEXT: entry: 1030 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1031 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1032 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 1033 // CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 1034 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1035 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1036 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1037 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1038 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1039 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1040 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1041 // CHECK-EH-03: if.then: 1042 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 1043 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1044 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 1045 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1046 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1047 // CHECK-EH-03: nrvo.unused: 1048 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1049 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 1050 // CHECK-EH-03: nrvo.skipdtor: 1051 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 1052 // CHECK-EH-03: if.else: 1053 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO1]], align 1 1054 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1055 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO1]], align 1 1056 // CHECK-EH-03-NEXT: [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1 1057 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] 1058 // CHECK-EH-03: nrvo.unused3: 1059 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1060 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR4]] 1061 // CHECK-EH-03: nrvo.skipdtor4: 1062 // CHECK-EH-03-NEXT: br label [[RETURN]] 1063 // CHECK-EH-03: return: 1064 // CHECK-EH-03-NEXT: ret void 1065 // 1066 // CHECK-EH-11-LABEL: @_Z5test8b( 1067 // CHECK-EH-11-NEXT: entry: 1068 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1069 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1070 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 1071 // CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 1072 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1073 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1074 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1075 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1076 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1077 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1078 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1079 // CHECK-EH-11: if.then: 1080 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 1081 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1082 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 1083 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1084 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1085 // CHECK-EH-11: nrvo.unused: 1086 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1087 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 1088 // CHECK-EH-11: nrvo.skipdtor: 1089 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 1090 // CHECK-EH-11: if.else: 1091 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO1]], align 1 1092 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1093 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO1]], align 1 1094 // CHECK-EH-11-NEXT: [[NRVO_VAL2:%.*]] = load i1, i1* [[NRVO1]], align 1 1095 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] 1096 // CHECK-EH-11: nrvo.unused3: 1097 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1098 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR4]] 1099 // CHECK-EH-11: nrvo.skipdtor4: 1100 // CHECK-EH-11-NEXT: br label [[RETURN]] 1101 // CHECK-EH-11: return: 1102 // CHECK-EH-11-NEXT: ret void 1103 // 1104 X test8(bool b) { 1105 if (b) { 1106 X x; 1107 return x; // NRVO happens 1108 } else { 1109 X y; 1110 return y; // NRVO happens 1111 } 1112 } 1113 1114 // CHECK-LABEL: @_Z5test9v( 1115 // CHECK-NEXT: entry: 1116 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1117 // CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 1118 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8* 1119 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1120 // CHECK-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]]) 1121 // CHECK-NEXT: call void @llvm.trap() 1122 // CHECK-NEXT: unreachable 1123 // 1124 // CHECK-EH-03-LABEL: @_Z5test9v( 1125 // CHECK-EH-03-NEXT: entry: 1126 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1127 // CHECK-EH-03-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 1128 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8* 1129 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1130 // CHECK-EH-03-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]]) 1131 // CHECK-EH-03-NEXT: call void @llvm.trap() 1132 // CHECK-EH-03-NEXT: unreachable 1133 // 1134 // CHECK-EH-11-LABEL: @_Z5test9v( 1135 // CHECK-EH-11-NEXT: entry: 1136 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1137 // CHECK-EH-11-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 1138 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %struct.Y* [[AGG_RESULT:%.*]] to i8* 1139 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1140 // CHECK-EH-11-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* sret([[STRUCT_Y]]) align 1 [[TMP]]) 1141 // CHECK-EH-11-NEXT: call void @llvm.trap() 1142 // CHECK-EH-11-NEXT: unreachable 1143 // 1144 Y<int> test9() { 1145 Y<int>::f(); 1146 } 1147 1148 // CHECK-LABEL: @_Z6test10b( 1149 // CHECK-NEXT: entry: 1150 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1151 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1152 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1153 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1154 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1155 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1156 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1157 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1158 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1159 // CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1160 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1161 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1162 // CHECK: if.then: 1163 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1164 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1165 // CHECK-NEXT: br label [[CLEANUP:%.*]] 1166 // CHECK: if.else: 1167 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1168 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1169 // CHECK-NEXT: br label [[CLEANUP]] 1170 // CHECK: cleanup: 1171 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1172 // CHECK-NEXT: ret void 1173 // 1174 // CHECK-EH-03-LABEL: @_Z6test10b( 1175 // CHECK-EH-03-NEXT: entry: 1176 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1177 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1178 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1179 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1180 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1181 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1182 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1183 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1184 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1185 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1186 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1187 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1188 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1189 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1190 // CHECK-EH-03: if.then: 1191 // 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]]) 1192 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1193 // CHECK-EH-03: invoke.cont: 1194 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1195 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 1196 // CHECK-EH-03: lpad: 1197 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1198 // CHECK-EH-03-NEXT: cleanup 1199 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1200 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1201 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1202 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1203 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1204 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1205 // CHECK-EH-03: if.else: 1206 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1207 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] 1208 // CHECK-EH-03: invoke.cont1: 1209 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1210 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1211 // CHECK-EH-03: cleanup: 1212 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1213 // CHECK-EH-03-NEXT: ret void 1214 // CHECK-EH-03: invoke.cont2: 1215 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1216 // CHECK-EH-03: eh.resume: 1217 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1218 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1219 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1220 // CHECK-EH-03-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1221 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL4]] 1222 // CHECK-EH-03: terminate.lpad: 1223 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 1224 // CHECK-EH-03-NEXT: catch i8* null 1225 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 1226 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP9]]) 1227 // CHECK-EH-03-NEXT: unreachable 1228 // 1229 // CHECK-EH-11-LABEL: @_Z6test10b( 1230 // CHECK-EH-11-NEXT: entry: 1231 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1232 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1233 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1234 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1235 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1236 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1237 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1238 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1239 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1240 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1241 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1242 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1243 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1244 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1245 // CHECK-EH-11: if.then: 1246 // 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]]) 1247 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1248 // CHECK-EH-11: invoke.cont: 1249 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1250 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 1251 // CHECK-EH-11: lpad: 1252 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1253 // CHECK-EH-11-NEXT: cleanup 1254 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1255 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1256 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1257 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1258 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1259 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 1260 // CHECK-EH-11: if.else: 1261 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1262 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] 1263 // CHECK-EH-11: invoke.cont1: 1264 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1265 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1266 // CHECK-EH-11: cleanup: 1267 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1268 // CHECK-EH-11-NEXT: ret void 1269 // CHECK-EH-11: eh.resume: 1270 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1271 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1272 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1273 // CHECK-EH-11-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1274 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL3]] 1275 // 1276 X test10(bool b) { // http://wg21.link/p2025r2#ex-3 1277 X x; 1278 if (b) 1279 return x; // NRVO is impossible 1280 else 1281 return X(); 1282 } 1283 1284 // CHECK-LABEL: @_Z6test11b( 1285 // CHECK-NEXT: entry: 1286 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1287 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1288 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1289 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1290 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1291 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1292 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1293 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1294 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1295 // CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1296 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1297 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1298 // CHECK: if.then: 1299 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1300 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1301 // CHECK-NEXT: br label [[CLEANUP:%.*]] 1302 // CHECK: if.end: 1303 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1304 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1305 // CHECK-NEXT: br label [[CLEANUP]] 1306 // CHECK: cleanup: 1307 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1308 // CHECK-NEXT: ret void 1309 // 1310 // CHECK-EH-03-LABEL: @_Z6test11b( 1311 // CHECK-EH-03-NEXT: entry: 1312 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1313 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1314 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1315 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1316 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1317 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1318 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1319 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1320 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1321 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1322 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1323 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1324 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1325 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1326 // CHECK-EH-03: if.then: 1327 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1328 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1329 // CHECK-EH-03: invoke.cont: 1330 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1331 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 1332 // CHECK-EH-03: lpad: 1333 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1334 // CHECK-EH-03-NEXT: cleanup 1335 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1336 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1337 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1338 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1339 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1340 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1341 // CHECK-EH-03: if.end: 1342 // 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]]) 1343 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] 1344 // CHECK-EH-03: invoke.cont1: 1345 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1346 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1347 // CHECK-EH-03: cleanup: 1348 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1349 // CHECK-EH-03-NEXT: ret void 1350 // CHECK-EH-03: invoke.cont2: 1351 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1352 // CHECK-EH-03: eh.resume: 1353 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1354 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1355 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1356 // CHECK-EH-03-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1357 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL4]] 1358 // CHECK-EH-03: terminate.lpad: 1359 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 1360 // CHECK-EH-03-NEXT: catch i8* null 1361 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 1362 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP9]]) 1363 // CHECK-EH-03-NEXT: unreachable 1364 // 1365 // CHECK-EH-11-LABEL: @_Z6test11b( 1366 // CHECK-EH-11-NEXT: entry: 1367 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1368 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1369 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1370 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1371 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1372 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1373 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1374 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1375 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1376 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1377 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1378 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1379 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1380 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1381 // CHECK-EH-11: if.then: 1382 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1383 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1384 // CHECK-EH-11: invoke.cont: 1385 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1386 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 1387 // CHECK-EH-11: lpad: 1388 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1389 // CHECK-EH-11-NEXT: cleanup 1390 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1391 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1392 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1393 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1394 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1395 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 1396 // CHECK-EH-11: if.end: 1397 // 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]]) 1398 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] 1399 // CHECK-EH-11: invoke.cont1: 1400 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1401 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1402 // CHECK-EH-11: cleanup: 1403 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1404 // CHECK-EH-11-NEXT: ret void 1405 // CHECK-EH-11: eh.resume: 1406 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1407 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1408 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1409 // CHECK-EH-11-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1410 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL3]] 1411 // 1412 X test11(bool b) { // http://wg21.link/p2025r2#ex-5 1413 X x; 1414 if (b) 1415 return X(); 1416 return x; // NRVO is impossible 1417 } 1418 1419 // CHECK-LABEL: @_Z6test12b( 1420 // CHECK-NEXT: entry: 1421 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1422 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1423 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 1424 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1425 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1426 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1427 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1428 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1429 // CHECK-NEXT: br label [[DO_BODY:%.*]] 1430 // CHECK: do.body: 1431 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 1432 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1433 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1434 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1435 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1436 // CHECK: if.then: 1437 // CHECK-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 1438 // CHECK-NEXT: br label [[CLEANUP:%.*]] 1439 // CHECK: if.end: 1440 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 1441 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1442 // CHECK-NEXT: br label [[CLEANUP]] 1443 // CHECK: cleanup: 1444 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1445 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1446 // CHECK: nrvo.unused: 1447 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1448 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 1449 // CHECK: nrvo.skipdtor: 1450 // CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 1451 // CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 1452 // CHECK-NEXT: i32 2, label [[DO_END:%.*]] 1453 // CHECK-NEXT: i32 1, label [[RETURN:%.*]] 1454 // CHECK-NEXT: ] 1455 // CHECK: do.end: 1456 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1457 // CHECK-NEXT: br label [[RETURN]] 1458 // CHECK: return: 1459 // CHECK-NEXT: ret void 1460 // CHECK: unreachable: 1461 // CHECK-NEXT: unreachable 1462 // 1463 // CHECK-EH-03-LABEL: @_Z6test12b( 1464 // CHECK-EH-03-NEXT: entry: 1465 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1466 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1467 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 1468 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1469 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1470 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1471 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1472 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1473 // CHECK-EH-03-NEXT: br label [[DO_BODY:%.*]] 1474 // CHECK-EH-03: do.body: 1475 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 1476 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1477 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1478 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1479 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1480 // CHECK-EH-03: if.then: 1481 // CHECK-EH-03-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 1482 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 1483 // CHECK-EH-03: if.end: 1484 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 1485 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1486 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1487 // CHECK-EH-03: cleanup: 1488 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1489 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1490 // CHECK-EH-03: nrvo.unused: 1491 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1492 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 1493 // CHECK-EH-03: nrvo.skipdtor: 1494 // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 1495 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 1496 // CHECK-EH-03-NEXT: i32 2, label [[DO_END:%.*]] 1497 // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] 1498 // CHECK-EH-03-NEXT: ] 1499 // CHECK-EH-03: do.end: 1500 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1501 // CHECK-EH-03-NEXT: br label [[RETURN]] 1502 // CHECK-EH-03: return: 1503 // CHECK-EH-03-NEXT: ret void 1504 // CHECK-EH-03: unreachable: 1505 // CHECK-EH-03-NEXT: unreachable 1506 // 1507 // CHECK-EH-11-LABEL: @_Z6test12b( 1508 // CHECK-EH-11-NEXT: entry: 1509 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1510 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1511 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 1512 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1513 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1514 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1515 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1516 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1517 // CHECK-EH-11-NEXT: br label [[DO_BODY:%.*]] 1518 // CHECK-EH-11: do.body: 1519 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 1520 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1521 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1522 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1523 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1524 // CHECK-EH-11: if.then: 1525 // CHECK-EH-11-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 1526 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 1527 // CHECK-EH-11: if.end: 1528 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 1529 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1530 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1531 // CHECK-EH-11: cleanup: 1532 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 1533 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 1534 // CHECK-EH-11: nrvo.unused: 1535 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1536 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 1537 // CHECK-EH-11: nrvo.skipdtor: 1538 // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 1539 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 1540 // CHECK-EH-11-NEXT: i32 2, label [[DO_END:%.*]] 1541 // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] 1542 // CHECK-EH-11-NEXT: ] 1543 // CHECK-EH-11: do.end: 1544 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1545 // CHECK-EH-11-NEXT: br label [[RETURN]] 1546 // CHECK-EH-11: return: 1547 // CHECK-EH-11-NEXT: ret void 1548 // CHECK-EH-11: unreachable: 1549 // CHECK-EH-11-NEXT: unreachable 1550 // 1551 X test12(bool b) { // http://wg21.link/p2025r2#ex-6 1552 do { 1553 X x; 1554 if (b) 1555 break; 1556 return x; // NRVO happens 1557 } while (false); 1558 return X(); 1559 } 1560 1561 // CHECK-LABEL: @_Z6test13b( 1562 // CHECK-NEXT: entry: 1563 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1564 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1565 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1566 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1567 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1568 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1569 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1570 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1571 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1572 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1573 // CHECK: if.then: 1574 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1575 // CHECK-NEXT: br label [[RETURN:%.*]] 1576 // CHECK: if.end: 1577 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1578 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1579 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1580 // CHECK-NEXT: br label [[RETURN]] 1581 // CHECK: return: 1582 // CHECK-NEXT: ret void 1583 // 1584 // CHECK-EH-03-LABEL: @_Z6test13b( 1585 // CHECK-EH-03-NEXT: entry: 1586 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1587 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1588 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1589 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1590 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1591 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1592 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1593 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1594 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1595 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1596 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1597 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1598 // CHECK-EH-03: if.then: 1599 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1600 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 1601 // CHECK-EH-03: if.end: 1602 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1603 // 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]]) 1604 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1605 // CHECK-EH-03: invoke.cont: 1606 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1607 // CHECK-EH-03-NEXT: br label [[RETURN]] 1608 // CHECK-EH-03: lpad: 1609 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 1610 // CHECK-EH-03-NEXT: cleanup 1611 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 1612 // CHECK-EH-03-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 1613 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 1614 // CHECK-EH-03-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 1615 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1616 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1617 // CHECK-EH-03: invoke.cont1: 1618 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1619 // CHECK-EH-03: return: 1620 // CHECK-EH-03-NEXT: ret void 1621 // CHECK-EH-03: eh.resume: 1622 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1623 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1624 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1625 // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1626 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL2]] 1627 // CHECK-EH-03: terminate.lpad: 1628 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 1629 // CHECK-EH-03-NEXT: catch i8* null 1630 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 1631 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP9]]) 1632 // CHECK-EH-03-NEXT: unreachable 1633 // 1634 // CHECK-EH-11-LABEL: @_Z6test13b( 1635 // CHECK-EH-11-NEXT: entry: 1636 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1637 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1638 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1639 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1640 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1641 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1642 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1643 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1644 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1645 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 1646 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 1647 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1648 // CHECK-EH-11: if.then: 1649 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 1650 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 1651 // CHECK-EH-11: if.end: 1652 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1653 // 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]]) 1654 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1655 // CHECK-EH-11: invoke.cont: 1656 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1657 // CHECK-EH-11-NEXT: br label [[RETURN]] 1658 // CHECK-EH-11: lpad: 1659 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 1660 // CHECK-EH-11-NEXT: cleanup 1661 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 1662 // CHECK-EH-11-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 1663 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 1664 // CHECK-EH-11-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 1665 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1666 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 1667 // CHECK-EH-11: return: 1668 // CHECK-EH-11-NEXT: ret void 1669 // CHECK-EH-11: eh.resume: 1670 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1671 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1672 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1673 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1674 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 1675 // 1676 X test13(bool b) { // http://wg21.link/p2025r2#ex-7 1677 if (b) 1678 return X(); 1679 X x; 1680 return x; // FIXME: NRVO could happen, but doesn't 1681 } 1682 1683 // CHECK-LABEL: @_Z6test14b( 1684 // CHECK-NEXT: entry: 1685 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1686 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1687 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1688 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1689 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1690 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1691 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1692 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1693 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1694 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1695 // CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1696 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1697 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1698 // CHECK: if.then: 1699 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1700 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1701 // CHECK-NEXT: br label [[CLEANUP:%.*]] 1702 // CHECK: if.end: 1703 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1704 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1705 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1706 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1707 // CHECK-NEXT: br label [[CLEANUP]] 1708 // CHECK: cleanup: 1709 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1710 // CHECK-NEXT: ret void 1711 // 1712 // CHECK-EH-03-LABEL: @_Z6test14b( 1713 // CHECK-EH-03-NEXT: entry: 1714 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1715 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1716 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1717 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1718 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1719 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1720 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1721 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1722 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1723 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1724 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1725 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1726 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1727 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1728 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1729 // CHECK-EH-03: if.then: 1730 // 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]]) 1731 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1732 // CHECK-EH-03: invoke.cont: 1733 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1734 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 1735 // CHECK-EH-03: lpad: 1736 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1737 // CHECK-EH-03-NEXT: cleanup 1738 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1739 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1740 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1741 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1742 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7:%.*]] 1743 // CHECK-EH-03: if.end: 1744 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1745 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1746 // CHECK-EH-03: invoke.cont1: 1747 // 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]]) 1748 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1749 // CHECK-EH-03: invoke.cont3: 1750 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1751 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1752 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]] 1753 // CHECK-EH-03: lpad2: 1754 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } 1755 // CHECK-EH-03-NEXT: cleanup 1756 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 1757 // CHECK-EH-03-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 4 1758 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 1759 // CHECK-EH-03-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 1760 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1761 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1762 // CHECK-EH-03: invoke.cont4: 1763 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1764 // CHECK-EH-03: invoke.cont5: 1765 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 1766 // CHECK-EH-03: cleanup: 1767 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1768 // CHECK-EH-03-NEXT: ret void 1769 // CHECK-EH-03: ehcleanup: 1770 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1771 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]] 1772 // CHECK-EH-03: invoke.cont6: 1773 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1774 // CHECK-EH-03: eh.resume: 1775 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1776 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1777 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1778 // CHECK-EH-03-NEXT: [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1779 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL11]] 1780 // CHECK-EH-03: terminate.lpad: 1781 // CHECK-EH-03-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } 1782 // CHECK-EH-03-NEXT: catch i8* null 1783 // CHECK-EH-03-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 1784 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) 1785 // CHECK-EH-03-NEXT: unreachable 1786 // 1787 // CHECK-EH-11-LABEL: @_Z6test14b( 1788 // CHECK-EH-11-NEXT: entry: 1789 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1790 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1791 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1792 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1793 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1794 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1795 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1796 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1797 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1798 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1799 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1800 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1801 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1802 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1803 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1804 // CHECK-EH-11: if.then: 1805 // 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]]) 1806 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1807 // CHECK-EH-11: invoke.cont: 1808 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1809 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 1810 // CHECK-EH-11: lpad: 1811 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1812 // CHECK-EH-11-NEXT: cleanup 1813 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1814 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1815 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1816 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1817 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5:%.*]] 1818 // CHECK-EH-11: if.end: 1819 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1820 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1821 // CHECK-EH-11: invoke.cont1: 1822 // 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]]) 1823 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1824 // CHECK-EH-11: invoke.cont3: 1825 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1826 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1827 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 1828 // CHECK-EH-11: lpad2: 1829 // CHECK-EH-11-NEXT: [[TMP11:%.*]] = landingpad { i8*, i32 } 1830 // CHECK-EH-11-NEXT: cleanup 1831 // CHECK-EH-11-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0 1832 // CHECK-EH-11-NEXT: store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4 1833 // CHECK-EH-11-NEXT: [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1 1834 // CHECK-EH-11-NEXT: store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4 1835 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1836 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 1837 // CHECK-EH-11: cleanup: 1838 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1839 // CHECK-EH-11-NEXT: ret void 1840 // CHECK-EH-11: ehcleanup: 1841 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1842 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 1843 // CHECK-EH-11: eh.resume: 1844 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1845 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1846 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1847 // CHECK-EH-11-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1848 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL8]] 1849 // 1850 X test14(bool b) { // http://wg21.link/p2025r2#ex-8 1851 X x; 1852 if (b) 1853 return x; 1854 X y; 1855 return y; // FIXME: NRVO could happen, but doesn't 1856 } 1857 1858 // CHECK-LABEL: @_Z6test15b( 1859 // CHECK-NEXT: entry: 1860 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1861 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1862 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1863 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1864 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1865 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1866 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1867 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1868 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1869 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1870 // CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1871 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1872 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1873 // CHECK: if.then: 1874 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1875 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1876 // CHECK-NEXT: br label [[CLEANUP:%.*]] 1877 // CHECK: if.end: 1878 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1879 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1880 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1881 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1882 // CHECK-NEXT: br label [[CLEANUP]] 1883 // CHECK: cleanup: 1884 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1885 // CHECK-NEXT: ret void 1886 // 1887 // CHECK-EH-03-LABEL: @_Z6test15b( 1888 // CHECK-EH-03-NEXT: entry: 1889 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1890 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1891 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1892 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1893 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1894 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1895 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1896 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1897 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1898 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1899 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1900 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1901 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1902 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1903 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1904 // CHECK-EH-03: if.then: 1905 // 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]]) 1906 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1907 // CHECK-EH-03: invoke.cont: 1908 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1909 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 1910 // CHECK-EH-03: lpad: 1911 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1912 // CHECK-EH-03-NEXT: cleanup 1913 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1914 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1915 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1916 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1917 // CHECK-EH-03-NEXT: br label [[EHCLEANUP7:%.*]] 1918 // CHECK-EH-03: if.end: 1919 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1920 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1921 // CHECK-EH-03: invoke.cont1: 1922 // 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]]) 1923 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1924 // CHECK-EH-03: invoke.cont3: 1925 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1926 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1927 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD1]] 1928 // CHECK-EH-03: lpad2: 1929 // CHECK-EH-03-NEXT: [[TMP10:%.*]] = landingpad { i8*, i32 } 1930 // CHECK-EH-03-NEXT: cleanup 1931 // CHECK-EH-03-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0 1932 // CHECK-EH-03-NEXT: store i8* [[TMP11]], i8** [[EXN_SLOT]], align 4 1933 // CHECK-EH-03-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 1 1934 // CHECK-EH-03-NEXT: store i32 [[TMP12]], i32* [[EHSELECTOR_SLOT]], align 4 1935 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1936 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 1937 // CHECK-EH-03: invoke.cont4: 1938 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 1939 // CHECK-EH-03: invoke.cont5: 1940 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 1941 // CHECK-EH-03: cleanup: 1942 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1943 // CHECK-EH-03-NEXT: ret void 1944 // CHECK-EH-03: ehcleanup: 1945 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1946 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[TERMINATE_LPAD]] 1947 // CHECK-EH-03: invoke.cont6: 1948 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 1949 // CHECK-EH-03: eh.resume: 1950 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 1951 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 1952 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 1953 // CHECK-EH-03-NEXT: [[LPAD_VAL11:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 1954 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL11]] 1955 // CHECK-EH-03: terminate.lpad: 1956 // CHECK-EH-03-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } 1957 // CHECK-EH-03-NEXT: catch i8* null 1958 // CHECK-EH-03-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 1959 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) 1960 // CHECK-EH-03-NEXT: unreachable 1961 // 1962 // CHECK-EH-11-LABEL: @_Z6test15b( 1963 // CHECK-EH-11-NEXT: entry: 1964 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 1965 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 1966 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 1967 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 1968 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 1969 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 1970 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 1971 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 1972 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 1973 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 1974 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 1975 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 1976 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i8, i8* [[B_ADDR]], align 1 1977 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP2]] to i1 1978 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1979 // CHECK-EH-11: if.then: 1980 // 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]]) 1981 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 1982 // CHECK-EH-11: invoke.cont: 1983 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 1984 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 1985 // CHECK-EH-11: lpad: 1986 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 1987 // CHECK-EH-11-NEXT: cleanup 1988 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 1989 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 1990 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 1991 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 1992 // CHECK-EH-11-NEXT: br label [[EHCLEANUP5:%.*]] 1993 // CHECK-EH-11: if.end: 1994 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 1995 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 1996 // CHECK-EH-11: invoke.cont1: 1997 // 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]]) 1998 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] 1999 // CHECK-EH-11: invoke.cont3: 2000 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2001 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2002 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2003 // CHECK-EH-11: lpad2: 2004 // CHECK-EH-11-NEXT: [[TMP11:%.*]] = landingpad { i8*, i32 } 2005 // CHECK-EH-11-NEXT: cleanup 2006 // CHECK-EH-11-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0 2007 // CHECK-EH-11-NEXT: store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4 2008 // CHECK-EH-11-NEXT: [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1 2009 // CHECK-EH-11-NEXT: store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4 2010 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2011 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 2012 // CHECK-EH-11: cleanup: 2013 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2014 // CHECK-EH-11-NEXT: ret void 2015 // CHECK-EH-11: ehcleanup: 2016 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2017 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 2018 // CHECK-EH-11: eh.resume: 2019 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2020 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2021 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2022 // CHECK-EH-11-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2023 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL8]] 2024 // 2025 X test15(bool b) { // http://wg21.link/p2025r2#ex-15 2026 X x; 2027 if (b) 2028 return (x); 2029 X y; 2030 return ((y)); // FIXME: NRVO could happen, but doesn't 2031 } 2032 2033 #ifdef CXX11 2034 // CHECK-EH-11-LABEL: @_Z6test16v( 2035 // CHECK-EH-11-NEXT: entry: 2036 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 2037 // CHECK-EH-11-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_X]], align 1 2038 // CHECK-EH-11-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 4 2039 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2040 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2041 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2042 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 0 2043 // CHECK-EH-11-NEXT: store %class.X* [[X]], %class.X** [[TMP2]], align 4 2044 // CHECK-EH-11-NEXT: invoke void @"_ZZ6test16vENK3$_0clEv"(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP]], %class.anon* noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) 2045 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2046 // CHECK-EH-11: invoke.cont: 2047 // CHECK-EH-11-NEXT: invoke void @_Z8ConsumeX1X(%class.X* noundef [[AGG_TMP]]) 2048 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] 2049 // CHECK-EH-11: invoke.cont2: 2050 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) 2051 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2052 // CHECK-EH-11-NEXT: ret void 2053 // CHECK-EH-11: lpad: 2054 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } 2055 // CHECK-EH-11-NEXT: cleanup 2056 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0 2057 // CHECK-EH-11-NEXT: store i8* [[TMP6]], i8** [[EXN_SLOT]], align 4 2058 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 1 2059 // CHECK-EH-11-NEXT: store i32 [[TMP7]], i32* [[EHSELECTOR_SLOT]], align 4 2060 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 2061 // CHECK-EH-11: lpad1: 2062 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 2063 // CHECK-EH-11-NEXT: cleanup 2064 // CHECK-EH-11-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 2065 // CHECK-EH-11-NEXT: store i8* [[TMP9]], i8** [[EXN_SLOT]], align 4 2066 // CHECK-EH-11-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 1 2067 // CHECK-EH-11-NEXT: store i32 [[TMP10]], i32* [[EHSELECTOR_SLOT]], align 4 2068 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) 2069 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 2070 // CHECK-EH-11: ehcleanup: 2071 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2072 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 2073 // CHECK-EH-11: eh.resume: 2074 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2075 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2076 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2077 // CHECK-EH-11-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2078 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL5]] 2079 // 2080 void test16() { // http://wg21.link/p2025r2#ex-9 2081 X x; 2082 ConsumeX([&] { 2083 X y(x); 2084 return y; // NRVO happens 2085 }()); 2086 } 2087 #endif 2088 2089 // CHECK-LABEL: @_Z6test17i( 2090 // CHECK-NEXT: entry: 2091 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2092 // CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2093 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2094 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2095 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2096 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2097 // CHECK-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2098 // CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] 2099 // CHECK: if.then: 2100 // CHECK-NEXT: br label [[IMPOSSIBLE:%.*]] 2101 // CHECK: impossible: 2102 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2103 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 2104 // CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] 2105 // CHECK: if.then1: 2106 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2107 // CHECK-NEXT: br label [[RETURN:%.*]] 2108 // CHECK: if.end: 2109 // CHECK-NEXT: br label [[IF_END2]] 2110 // CHECK: if.end2: 2111 // CHECK-NEXT: br label [[WHILE_BODY:%.*]] 2112 // CHECK: while.body: 2113 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 2114 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2115 // CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4 2116 // CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 2117 // CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] 2118 // CHECK: if.then4: 2119 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 2120 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2121 // CHECK-NEXT: br label [[CLEANUP:%.*]] 2122 // CHECK: if.end5: 2123 // CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2124 // CHECK-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 2125 // CHECK-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] 2126 // CHECK: if.then7: 2127 // CHECK-NEXT: store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4 2128 // CHECK-NEXT: br label [[CLEANUP]] 2129 // CHECK: if.end8: 2130 // CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4 2131 // CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 2132 // CHECK-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] 2133 // CHECK: if.then10: 2134 // CHECK-NEXT: store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4 2135 // CHECK-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP10:![0-9]+]] 2136 // CHECK: if.end11: 2137 // CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4 2138 // CHECK-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 2139 // CHECK-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] 2140 // CHECK: if.then13: 2141 // CHECK-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 2142 // CHECK-NEXT: br label [[CLEANUP]] 2143 // CHECK: if.end14: 2144 // CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4 2145 // CHECK-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 2146 // CHECK-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] 2147 // CHECK: if.then16: 2148 // CHECK-NEXT: call void @exit(i32 noundef 1) 2149 // CHECK-NEXT: br label [[IF_END17]] 2150 // CHECK: if.end17: 2151 // CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4 2152 // CHECK-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 2153 // CHECK-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] 2154 // CHECK: if.then19: 2155 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 2156 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2157 // CHECK-NEXT: br label [[CLEANUP]] 2158 // CHECK: if.end20: 2159 // CHECK-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2160 // CHECK-NEXT: br label [[CLEANUP]] 2161 // CHECK: cleanup: 2162 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2163 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2164 // CHECK: nrvo.unused: 2165 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2166 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 2167 // CHECK: nrvo.skipdtor: 2168 // CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2169 // CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2170 // CHECK-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2171 // CHECK-NEXT: i32 1, label [[RETURN]] 2172 // CHECK-NEXT: i32 4, label [[WHILE_END:%.*]] 2173 // CHECK-NEXT: i32 3, label [[WHILE_BODY]] 2174 // CHECK-NEXT: i32 2, label [[IMPOSSIBLE]] 2175 // CHECK-NEXT: ] 2176 // CHECK: cleanup.cont: 2177 // CHECK-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP10]] 2178 // CHECK: while.end: 2179 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2180 // CHECK-NEXT: br label [[RETURN]] 2181 // CHECK: return: 2182 // CHECK-NEXT: ret void 2183 // CHECK: unreachable: 2184 // CHECK-NEXT: unreachable 2185 // 2186 // CHECK-EH-03-LABEL: @_Z6test17i( 2187 // CHECK-EH-03-NEXT: entry: 2188 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2189 // CHECK-EH-03-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2190 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2191 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2192 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2193 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2194 // CHECK-EH-03-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2195 // CHECK-EH-03-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] 2196 // CHECK-EH-03: if.then: 2197 // CHECK-EH-03-NEXT: br label [[IMPOSSIBLE:%.*]] 2198 // CHECK-EH-03: impossible: 2199 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2200 // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 2201 // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] 2202 // CHECK-EH-03: if.then1: 2203 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2204 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 2205 // CHECK-EH-03: if.end: 2206 // CHECK-EH-03-NEXT: br label [[IF_END2]] 2207 // CHECK-EH-03: if.end2: 2208 // CHECK-EH-03-NEXT: br label [[WHILE_BODY:%.*]] 2209 // CHECK-EH-03: while.body: 2210 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 2211 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2212 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4 2213 // CHECK-EH-03-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 2214 // CHECK-EH-03-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] 2215 // CHECK-EH-03: if.then4: 2216 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 2217 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2218 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 2219 // CHECK-EH-03: if.end5: 2220 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2221 // CHECK-EH-03-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 2222 // CHECK-EH-03-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] 2223 // CHECK-EH-03: if.then7: 2224 // CHECK-EH-03-NEXT: store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4 2225 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2226 // CHECK-EH-03: if.end8: 2227 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4 2228 // CHECK-EH-03-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 2229 // CHECK-EH-03-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] 2230 // CHECK-EH-03: if.then10: 2231 // CHECK-EH-03-NEXT: store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4 2232 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2233 // CHECK-EH-03: if.end11: 2234 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4 2235 // CHECK-EH-03-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 2236 // CHECK-EH-03-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] 2237 // CHECK-EH-03: if.then13: 2238 // CHECK-EH-03-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 2239 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2240 // CHECK-EH-03: if.end14: 2241 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4 2242 // CHECK-EH-03-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 2243 // CHECK-EH-03-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] 2244 // CHECK-EH-03: if.then16: 2245 // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) 2246 // CHECK-EH-03-NEXT: br label [[IF_END17]] 2247 // CHECK-EH-03: if.end17: 2248 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4 2249 // CHECK-EH-03-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 2250 // CHECK-EH-03-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] 2251 // CHECK-EH-03: if.then19: 2252 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 2253 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2254 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2255 // CHECK-EH-03: if.end20: 2256 // CHECK-EH-03-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2257 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2258 // CHECK-EH-03: cleanup: 2259 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2260 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2261 // CHECK-EH-03: nrvo.unused: 2262 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2263 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 2264 // CHECK-EH-03: nrvo.skipdtor: 2265 // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2266 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2267 // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2268 // CHECK-EH-03-NEXT: i32 1, label [[RETURN]] 2269 // CHECK-EH-03-NEXT: i32 4, label [[WHILE_END:%.*]] 2270 // CHECK-EH-03-NEXT: i32 3, label [[WHILE_BODY]] 2271 // CHECK-EH-03-NEXT: i32 2, label [[IMPOSSIBLE]] 2272 // CHECK-EH-03-NEXT: ] 2273 // CHECK-EH-03: cleanup.cont: 2274 // CHECK-EH-03-NEXT: br label [[WHILE_BODY]] 2275 // CHECK-EH-03: while.end: 2276 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2277 // CHECK-EH-03-NEXT: br label [[RETURN]] 2278 // CHECK-EH-03: return: 2279 // CHECK-EH-03-NEXT: ret void 2280 // CHECK-EH-03: unreachable: 2281 // CHECK-EH-03-NEXT: unreachable 2282 // 2283 // CHECK-EH-11-LABEL: @_Z6test17i( 2284 // CHECK-EH-11-NEXT: entry: 2285 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2286 // CHECK-EH-11-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2287 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2288 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2289 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2290 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2291 // CHECK-EH-11-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2292 // CHECK-EH-11-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] 2293 // CHECK-EH-11: if.then: 2294 // CHECK-EH-11-NEXT: br label [[IMPOSSIBLE:%.*]] 2295 // CHECK-EH-11: impossible: 2296 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2297 // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 2298 // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] 2299 // CHECK-EH-11: if.then1: 2300 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2301 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 2302 // CHECK-EH-11: if.end: 2303 // CHECK-EH-11-NEXT: br label [[IF_END2]] 2304 // CHECK-EH-11: if.end2: 2305 // CHECK-EH-11-NEXT: br label [[WHILE_BODY:%.*]] 2306 // CHECK-EH-11: while.body: 2307 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 2308 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2309 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i32, i32* [[I_ADDR]], align 4 2310 // CHECK-EH-11-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 2311 // CHECK-EH-11-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] 2312 // CHECK-EH-11: if.then4: 2313 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 2314 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2315 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 2316 // CHECK-EH-11: if.end5: 2317 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2318 // CHECK-EH-11-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 2319 // CHECK-EH-11-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] 2320 // CHECK-EH-11: if.then7: 2321 // CHECK-EH-11-NEXT: store i32 4, i32* [[CLEANUP_DEST_SLOT]], align 4 2322 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2323 // CHECK-EH-11: if.end8: 2324 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = load i32, i32* [[I_ADDR]], align 4 2325 // CHECK-EH-11-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 2326 // CHECK-EH-11-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] 2327 // CHECK-EH-11: if.then10: 2328 // CHECK-EH-11-NEXT: store i32 3, i32* [[CLEANUP_DEST_SLOT]], align 4 2329 // CHECK-EH-11-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP14:![0-9]+]] 2330 // CHECK-EH-11: if.end11: 2331 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = load i32, i32* [[I_ADDR]], align 4 2332 // CHECK-EH-11-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 2333 // CHECK-EH-11-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] 2334 // CHECK-EH-11: if.then13: 2335 // CHECK-EH-11-NEXT: store i32 2, i32* [[CLEANUP_DEST_SLOT]], align 4 2336 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2337 // CHECK-EH-11: if.end14: 2338 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = load i32, i32* [[I_ADDR]], align 4 2339 // CHECK-EH-11-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 2340 // CHECK-EH-11-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] 2341 // CHECK-EH-11: if.then16: 2342 // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) 2343 // CHECK-EH-11-NEXT: br label [[IF_END17]] 2344 // CHECK-EH-11: if.end17: 2345 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = load i32, i32* [[I_ADDR]], align 4 2346 // CHECK-EH-11-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 2347 // CHECK-EH-11-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] 2348 // CHECK-EH-11: if.then19: 2349 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 2350 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2351 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2352 // CHECK-EH-11: if.end20: 2353 // CHECK-EH-11-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2354 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2355 // CHECK-EH-11: cleanup: 2356 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2357 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2358 // CHECK-EH-11: nrvo.unused: 2359 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2360 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 2361 // CHECK-EH-11: nrvo.skipdtor: 2362 // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2363 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2364 // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2365 // CHECK-EH-11-NEXT: i32 1, label [[RETURN]] 2366 // CHECK-EH-11-NEXT: i32 4, label [[WHILE_END:%.*]] 2367 // CHECK-EH-11-NEXT: i32 3, label [[WHILE_BODY]] 2368 // CHECK-EH-11-NEXT: i32 2, label [[IMPOSSIBLE]] 2369 // CHECK-EH-11-NEXT: ] 2370 // CHECK-EH-11: cleanup.cont: 2371 // CHECK-EH-11-NEXT: br label [[WHILE_BODY]], !llvm.loop [[LOOP14]] 2372 // CHECK-EH-11: while.end: 2373 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2374 // CHECK-EH-11-NEXT: br label [[RETURN]] 2375 // CHECK-EH-11: return: 2376 // CHECK-EH-11-NEXT: ret void 2377 // CHECK-EH-11: unreachable: 2378 // CHECK-EH-11-NEXT: unreachable 2379 // 2380 X test17(int i) { // http://wg21.link/p2025r2#ex-10 2381 if (false) { 2382 impossible: 2383 if (i == 3) 2384 return X(); 2385 } 2386 2387 while (true) { 2388 X x; 2389 if (i == 0) 2390 return x; // NRVO happens 2391 if (i == 1) 2392 break; 2393 if (i == 2) 2394 continue; 2395 if (i == 3) 2396 goto impossible; 2397 if (i == 4) 2398 exit(1); 2399 if (i == 5) 2400 return x; // NRVO happens 2401 } 2402 return X(); 2403 } 2404 2405 // CHECK-LABEL: @_Z6test18i( 2406 // CHECK-NEXT: entry: 2407 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2408 // CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2409 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2410 // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2411 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 2412 // CHECK-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 2413 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2414 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2415 // CHECK-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2416 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 2417 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2418 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2419 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2420 // CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2421 // CHECK: if.then: 2422 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 2423 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2424 // CHECK-NEXT: br label [[CLEANUP:%.*]] 2425 // CHECK: if.end: 2426 // CHECK-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2427 // CHECK-NEXT: br label [[CLEANUP]] 2428 // CHECK: cleanup: 2429 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2430 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2431 // CHECK: nrvo.unused: 2432 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2433 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 2434 // CHECK: nrvo.skipdtor: 2435 // CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2436 // CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2437 // CHECK-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2438 // CHECK-NEXT: i32 1, label [[RETURN:%.*]] 2439 // CHECK-NEXT: ] 2440 // CHECK: cleanup.cont: 2441 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2442 // CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2443 // CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1 2444 // CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] 2445 // CHECK: if.then2: 2446 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2447 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2448 // CHECK-NEXT: br label [[CLEANUP4:%.*]] 2449 // CHECK: if.end3: 2450 // CHECK-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2451 // CHECK-NEXT: br label [[CLEANUP4]] 2452 // CHECK: cleanup4: 2453 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2454 // CHECK-NEXT: [[CLEANUP_DEST6:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2455 // CHECK-NEXT: switch i32 [[CLEANUP_DEST6]], label [[UNREACHABLE]] [ 2456 // CHECK-NEXT: i32 0, label [[CLEANUP_CONT7:%.*]] 2457 // CHECK-NEXT: i32 1, label [[RETURN]] 2458 // CHECK-NEXT: ] 2459 // CHECK: cleanup.cont6: 2460 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2461 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2462 // CHECK-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2463 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2464 // CHECK-NEXT: br label [[RETURN]] 2465 // CHECK: return: 2466 // CHECK-NEXT: ret void 2467 // CHECK: unreachable: 2468 // CHECK-NEXT: unreachable 2469 // 2470 // CHECK-EH-03-LABEL: @_Z6test18i( 2471 // CHECK-EH-03-NEXT: entry: 2472 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2473 // CHECK-EH-03-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2474 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2475 // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2476 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 2477 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2478 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2479 // CHECK-EH-03-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 2480 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2481 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2482 // CHECK-EH-03-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2483 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 2484 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2485 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2486 // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2487 // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2488 // CHECK-EH-03: if.then: 2489 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 2490 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2491 // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] 2492 // CHECK-EH-03: if.end: 2493 // CHECK-EH-03-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2494 // CHECK-EH-03-NEXT: br label [[CLEANUP]] 2495 // CHECK-EH-03: cleanup: 2496 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2497 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2498 // CHECK-EH-03: nrvo.unused: 2499 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2500 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 2501 // CHECK-EH-03: nrvo.skipdtor: 2502 // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2503 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2504 // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2505 // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] 2506 // CHECK-EH-03-NEXT: ] 2507 // CHECK-EH-03: cleanup.cont: 2508 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2509 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2510 // CHECK-EH-03-NEXT: [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1 2511 // CHECK-EH-03-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] 2512 // CHECK-EH-03: if.then2: 2513 // 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]]) 2514 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2515 // CHECK-EH-03: invoke.cont: 2516 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2517 // CHECK-EH-03-NEXT: br label [[CLEANUP4:%.*]] 2518 // CHECK-EH-03: lpad: 2519 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 2520 // CHECK-EH-03-NEXT: cleanup 2521 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 2522 // CHECK-EH-03-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 2523 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 2524 // CHECK-EH-03-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 2525 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2526 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 2527 // CHECK-EH-03: if.end3: 2528 // CHECK-EH-03-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2529 // CHECK-EH-03-NEXT: br label [[CLEANUP4]] 2530 // CHECK-EH-03: cleanup4: 2531 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2532 // CHECK-EH-03-NEXT: [[CLEANUP_DEST7:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2533 // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST7]], label [[UNREACHABLE]] [ 2534 // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT8:%.*]] 2535 // CHECK-EH-03-NEXT: i32 1, label [[RETURN]] 2536 // CHECK-EH-03-NEXT: ] 2537 // CHECK-EH-03: cleanup.cont6: 2538 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2539 // 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]]) 2540 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT10:%.*]] unwind label [[LPAD9:%.*]] 2541 // CHECK-EH-03: invoke.cont9: 2542 // CHECK-EH-03-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2543 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2544 // CHECK-EH-03-NEXT: br label [[RETURN]] 2545 // CHECK-EH-03: invoke.cont7: 2546 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 2547 // CHECK-EH-03: lpad8: 2548 // CHECK-EH-03-NEXT: [[TMP11:%.*]] = landingpad { i8*, i32 } 2549 // CHECK-EH-03-NEXT: cleanup 2550 // CHECK-EH-03-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0 2551 // CHECK-EH-03-NEXT: store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4 2552 // CHECK-EH-03-NEXT: [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1 2553 // CHECK-EH-03-NEXT: store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4 2554 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2555 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT12:%.*]] unwind label [[TERMINATE_LPAD]] 2556 // CHECK-EH-03: invoke.cont11: 2557 // CHECK-EH-03-NEXT: br label [[EH_RESUME]] 2558 // CHECK-EH-03: return: 2559 // CHECK-EH-03-NEXT: ret void 2560 // CHECK-EH-03: eh.resume: 2561 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2562 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2563 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2564 // CHECK-EH-03-NEXT: [[LPAD_VAL14:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2565 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL14]] 2566 // CHECK-EH-03: terminate.lpad: 2567 // CHECK-EH-03-NEXT: [[TMP15:%.*]] = landingpad { i8*, i32 } 2568 // CHECK-EH-03-NEXT: catch i8* null 2569 // CHECK-EH-03-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP15]], 0 2570 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP16]]) 2571 // CHECK-EH-03-NEXT: unreachable 2572 // CHECK-EH-03: unreachable: 2573 // CHECK-EH-03-NEXT: unreachable 2574 // 2575 // CHECK-EH-11-LABEL: @_Z6test18i( 2576 // CHECK-EH-11-NEXT: entry: 2577 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2578 // CHECK-EH-11-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 2579 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2580 // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 2581 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 2582 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2583 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2584 // CHECK-EH-11-NEXT: [[Z:%.*]] = alloca [[CLASS_X]], align 1 2585 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2586 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2587 // CHECK-EH-11-NEXT: store i32 [[I:%.*]], i32* [[I_ADDR]], align 4 2588 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 2589 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2590 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, i32* [[I_ADDR]], align 4 2591 // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2592 // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2593 // CHECK-EH-11: if.then: 2594 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 2595 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2596 // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] 2597 // CHECK-EH-11: if.end: 2598 // CHECK-EH-11-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2599 // CHECK-EH-11-NEXT: br label [[CLEANUP]] 2600 // CHECK-EH-11: cleanup: 2601 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2602 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2603 // CHECK-EH-11: nrvo.unused: 2604 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2605 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 2606 // CHECK-EH-11: nrvo.skipdtor: 2607 // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2608 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ 2609 // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] 2610 // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] 2611 // CHECK-EH-11-NEXT: ] 2612 // CHECK-EH-11: cleanup.cont: 2613 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2614 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = load i32, i32* [[I_ADDR]], align 4 2615 // CHECK-EH-11-NEXT: [[CMP1:%.*]] = icmp eq i32 [[TMP3]], 1 2616 // CHECK-EH-11-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] 2617 // CHECK-EH-11: if.then2: 2618 // 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]]) 2619 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2620 // CHECK-EH-11: invoke.cont: 2621 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2622 // CHECK-EH-11-NEXT: br label [[CLEANUP4:%.*]] 2623 // CHECK-EH-11: lpad: 2624 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 2625 // CHECK-EH-11-NEXT: cleanup 2626 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 2627 // CHECK-EH-11-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 2628 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 2629 // CHECK-EH-11-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 2630 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2631 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 2632 // CHECK-EH-11: if.end3: 2633 // CHECK-EH-11-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT]], align 4 2634 // CHECK-EH-11-NEXT: br label [[CLEANUP4]] 2635 // CHECK-EH-11: cleanup4: 2636 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2637 // CHECK-EH-11-NEXT: [[CLEANUP_DEST6:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT]], align 4 2638 // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST6]], label [[UNREACHABLE]] [ 2639 // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT7:%.*]] 2640 // CHECK-EH-11-NEXT: i32 1, label [[RETURN]] 2641 // CHECK-EH-11-NEXT: ] 2642 // CHECK-EH-11: cleanup.cont6: 2643 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2644 // 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]]) 2645 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]] 2646 // CHECK-EH-11: invoke.cont8: 2647 // CHECK-EH-11-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT]], align 4 2648 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2649 // CHECK-EH-11-NEXT: br label [[RETURN]] 2650 // CHECK-EH-11: lpad7: 2651 // CHECK-EH-11-NEXT: [[TMP11:%.*]] = landingpad { i8*, i32 } 2652 // CHECK-EH-11-NEXT: cleanup 2653 // CHECK-EH-11-NEXT: [[TMP12:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 0 2654 // CHECK-EH-11-NEXT: store i8* [[TMP12]], i8** [[EXN_SLOT]], align 4 2655 // CHECK-EH-11-NEXT: [[TMP13:%.*]] = extractvalue { i8*, i32 } [[TMP11]], 1 2656 // CHECK-EH-11-NEXT: store i32 [[TMP13]], i32* [[EHSELECTOR_SLOT]], align 4 2657 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Z]]) 2658 // CHECK-EH-11-NEXT: br label [[EH_RESUME]] 2659 // CHECK-EH-11: return: 2660 // CHECK-EH-11-NEXT: ret void 2661 // CHECK-EH-11: eh.resume: 2662 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2663 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2664 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2665 // CHECK-EH-11-NEXT: [[LPAD_VAL12:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2666 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL12]] 2667 // CHECK-EH-11: unreachable: 2668 // CHECK-EH-11-NEXT: unreachable 2669 // 2670 X test18(int i) { // http://wg21.link/p2025r2#ex-11 2671 { 2672 { 2673 X x; 2674 if (i == 0) 2675 return x; // NRVO happens 2676 } 2677 X y; 2678 if (i == 1) 2679 return y; // FIXME: NRVO could happen, but doesn't 2680 } 2681 X z; 2682 return z; // FIXME: NRVO could happen, but doesn't 2683 } 2684 2685 #ifdef CXX11 2686 // CHECK-EH-11-LABEL: @_Z6test19v( 2687 // CHECK-EH-11-NEXT: entry: 2688 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2689 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2690 // CHECK-EH-11-NEXT: [[L:%.*]] = alloca [[CLASS_X:%.*]], align 1 2691 // CHECK-EH-11-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 4 2692 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2693 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2694 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2695 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2696 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 2697 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2698 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 0 2699 // CHECK-EH-11-NEXT: store %class.X* [[AGG_RESULT]], %class.X** [[TMP3]], align 4 2700 // CHECK-EH-11-NEXT: invoke void @"_ZZ6test19vENK3$_1clEv"(%class.X* sret([[CLASS_X]]) align 1 [[L]], %class.anon.0* noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) 2701 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2702 // CHECK-EH-11: invoke.cont: 2703 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 2704 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[L]]) 2705 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2706 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2707 // CHECK-EH-11: lpad: 2708 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = landingpad { i8*, i32 } 2709 // CHECK-EH-11-NEXT: cleanup 2710 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = extractvalue { i8*, i32 } [[TMP6]], 0 2711 // CHECK-EH-11-NEXT: store i8* [[TMP7]], i8** [[EXN_SLOT]], align 4 2712 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP6]], 1 2713 // CHECK-EH-11-NEXT: store i32 [[TMP8]], i32* [[EHSELECTOR_SLOT]], align 4 2714 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2715 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 2716 // CHECK-EH-11: nrvo.unused: 2717 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2718 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 2719 // CHECK-EH-11: nrvo.skipdtor: 2720 // CHECK-EH-11-NEXT: ret void 2721 // CHECK-EH-11: eh.resume: 2722 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2723 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2724 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2725 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2726 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 2727 // 2728 X test19() { // http://wg21.link/p2025r2#ex-12 2729 X x; 2730 struct S { 2731 X f() { return X(); } 2732 }; 2733 auto L = [&x]() { return X(); }(); 2734 if constexpr (false) { 2735 return X(); 2736 } 2737 return x; // NRVO happens 2738 } 2739 2740 template <bool B> 2741 X test20() { // http://wg21.link/p2025r2#ex-18 2742 X x; 2743 if constexpr (B) { 2744 if (false) 2745 return X(); 2746 } 2747 return x; // FIXME: NRVO could happen when B == false, but doesn't 2748 } 2749 2750 // CHECK-EH-11-LABEL: @_Z17test20instantiatev( 2751 // CHECK-EH-11-NEXT: entry: 2752 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 2753 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 2754 // CHECK-EH-11-NEXT: call void @_Z6test20ILb1EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) 2755 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) 2756 // CHECK-EH-11-NEXT: call void @_Z6test20ILb0EE1Xv(%class.X* sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) 2757 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) 2758 // CHECK-EH-11-NEXT: ret void 2759 // 2760 void test20instantiate() { 2761 test20<true>(); 2762 test20<false>(); 2763 } 2764 #endif 2765 2766 // CHECK-LABEL: @_Z6test21v( 2767 // CHECK-NEXT: entry: 2768 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2769 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2770 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2771 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2772 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 2773 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2774 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 2775 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2776 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2777 // CHECK: nrvo.unused: 2778 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2779 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 2780 // CHECK: nrvo.skipdtor: 2781 // CHECK-NEXT: ret void 2782 // 2783 // CHECK-EH-03-LABEL: @_Z6test21v( 2784 // CHECK-EH-03-NEXT: entry: 2785 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2786 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2787 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2788 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2789 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 2790 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2791 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 2792 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2793 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2794 // CHECK-EH-03: nrvo.unused: 2795 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2796 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 2797 // CHECK-EH-03: nrvo.skipdtor: 2798 // CHECK-EH-03-NEXT: ret void 2799 // 2800 // CHECK-EH-11-LABEL: @_Z6test21v( 2801 // CHECK-EH-11-NEXT: entry: 2802 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2803 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2804 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2805 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2806 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 2807 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2808 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 2809 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2810 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2811 // CHECK-EH-11: nrvo.unused: 2812 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2813 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 2814 // CHECK-EH-11: nrvo.skipdtor: 2815 // CHECK-EH-11-NEXT: ret void 2816 // 2817 const volatile X test21() { // http://wg21.link/p2025r2#ex-19 2818 X x; 2819 return x; // NRVO happens 2820 } 2821 2822 // CHECK-LABEL: @_Z6test22v( 2823 // CHECK-NEXT: entry: 2824 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2825 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 2826 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2827 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2828 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2829 // CHECK-NEXT: call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2830 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2831 // CHECK-NEXT: ret void 2832 // 2833 // CHECK-EH-03-LABEL: @_Z6test22v( 2834 // CHECK-EH-03-NEXT: entry: 2835 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2836 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 2837 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2838 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2839 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2840 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2841 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2842 // 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]]) 2843 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2844 // CHECK-EH-03: invoke.cont: 2845 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2846 // CHECK-EH-03-NEXT: ret void 2847 // CHECK-EH-03: lpad: 2848 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 2849 // CHECK-EH-03-NEXT: cleanup 2850 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 2851 // CHECK-EH-03-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 2852 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 2853 // CHECK-EH-03-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 2854 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2855 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 2856 // CHECK-EH-03: invoke.cont1: 2857 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 2858 // CHECK-EH-03: eh.resume: 2859 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2860 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2861 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2862 // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2863 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL2]] 2864 // CHECK-EH-03: terminate.lpad: 2865 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } 2866 // CHECK-EH-03-NEXT: catch i8* null 2867 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 2868 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP8]]) 2869 // CHECK-EH-03-NEXT: unreachable 2870 // 2871 // CHECK-EH-11-LABEL: @_Z6test22v( 2872 // CHECK-EH-11-NEXT: entry: 2873 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2874 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 2875 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2876 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2877 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2878 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2879 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2880 // 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]]) 2881 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2882 // CHECK-EH-11: invoke.cont: 2883 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2884 // CHECK-EH-11-NEXT: ret void 2885 // CHECK-EH-11: lpad: 2886 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 2887 // CHECK-EH-11-NEXT: cleanup 2888 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0 2889 // CHECK-EH-11-NEXT: store i8* [[TMP4]], i8** [[EXN_SLOT]], align 4 2890 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 1 2891 // CHECK-EH-11-NEXT: store i32 [[TMP5]], i32* [[EHSELECTOR_SLOT]], align 4 2892 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 2893 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 2894 // CHECK-EH-11: eh.resume: 2895 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2896 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2897 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2898 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2899 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 2900 // 2901 X test22() { // http://wg21.link/p2025r2#ex-19 2902 volatile X x; 2903 return x; // NRVO is impossible 2904 } 2905 2906 // CHECK-LABEL: @_Z6test23b( 2907 // CHECK-NEXT: entry: 2908 // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2909 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 2910 // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2911 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 2912 // CHECK-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2913 // CHECK-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2914 // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 2915 // CHECK-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 2916 // CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 2917 // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 2918 // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2919 // CHECK: if.then: 2920 // CHECK-NEXT: store i1 false, i1* [[NRVO]], align 1 2921 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2922 // CHECK-NEXT: store i1 true, i1* [[NRVO]], align 1 2923 // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2924 // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2925 // CHECK: nrvo.unused: 2926 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2927 // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] 2928 // CHECK: nrvo.skipdtor: 2929 // CHECK-NEXT: br label [[RETURN:%.*]] 2930 // CHECK: if.end: 2931 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2932 // CHECK-NEXT: call void @_ZN1XC1ERVKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2933 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2934 // CHECK-NEXT: br label [[RETURN]] 2935 // CHECK: return: 2936 // CHECK-NEXT: ret void 2937 // 2938 // CHECK-EH-03-LABEL: @_Z6test23b( 2939 // CHECK-EH-03-NEXT: entry: 2940 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 2941 // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 2942 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 2943 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 2944 // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 2945 // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 2946 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 2947 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 2948 // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 2949 // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 2950 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 2951 // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 2952 // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 2953 // CHECK-EH-03: if.then: 2954 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 2955 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2956 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 2957 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 2958 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 2959 // CHECK-EH-03: nrvo.unused: 2960 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 2961 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 2962 // CHECK-EH-03: nrvo.skipdtor: 2963 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 2964 // CHECK-EH-03: if.end: 2965 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2966 // 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]]) 2967 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2968 // CHECK-EH-03: invoke.cont: 2969 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2970 // CHECK-EH-03-NEXT: br label [[RETURN]] 2971 // CHECK-EH-03: lpad: 2972 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 2973 // CHECK-EH-03-NEXT: cleanup 2974 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 2975 // CHECK-EH-03-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 2976 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 2977 // CHECK-EH-03-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 2978 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 2979 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 2980 // CHECK-EH-03: invoke.cont1: 2981 // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] 2982 // CHECK-EH-03: return: 2983 // CHECK-EH-03-NEXT: ret void 2984 // CHECK-EH-03: eh.resume: 2985 // CHECK-EH-03-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 2986 // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 2987 // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 2988 // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 2989 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL2]] 2990 // CHECK-EH-03: terminate.lpad: 2991 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 2992 // CHECK-EH-03-NEXT: catch i8* null 2993 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP8]], 0 2994 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP9]]) 2995 // CHECK-EH-03-NEXT: unreachable 2996 // 2997 // CHECK-EH-11-LABEL: @_Z6test23b( 2998 // CHECK-EH-11-NEXT: entry: 2999 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 3000 // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 3001 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 3002 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 3003 // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 4 3004 // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 3005 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 3006 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 3007 // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 3008 // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], i8* [[B_ADDR]], align 1 3009 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, i8* [[B_ADDR]], align 1 3010 // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 3011 // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 3012 // CHECK-EH-11: if.then: 3013 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 3014 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3015 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 3016 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 3017 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 3018 // CHECK-EH-11: nrvo.unused: 3019 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3020 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 3021 // CHECK-EH-11: nrvo.skipdtor: 3022 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 3023 // CHECK-EH-11: if.end: 3024 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 3025 // 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]]) 3026 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 3027 // CHECK-EH-11: invoke.cont: 3028 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 3029 // CHECK-EH-11-NEXT: br label [[RETURN]] 3030 // CHECK-EH-11: lpad: 3031 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 3032 // CHECK-EH-11-NEXT: cleanup 3033 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 3034 // CHECK-EH-11-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 4 3035 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 3036 // CHECK-EH-11-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 3037 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 3038 // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] 3039 // CHECK-EH-11: return: 3040 // CHECK-EH-11-NEXT: ret void 3041 // CHECK-EH-11: eh.resume: 3042 // CHECK-EH-11-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 4 3043 // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4 3044 // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0 3045 // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 3046 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL1]] 3047 // 3048 X test23(bool b) { // http://wg21.link/p2025r2#ex-19 3049 if (b) { 3050 const X x; 3051 return x; // NRVO happens 3052 } 3053 volatile X y; 3054 return y; // NRVO is impossible 3055 } 3056 3057 #ifdef __EXCEPTIONS 3058 // CHECK-EH-03-LABEL: @_Z6test24v( 3059 // CHECK-EH-03-NEXT: entry: 3060 // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 3061 // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 3062 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 3063 // CHECK-EH-03-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 3064 // CHECK-EH-03-NEXT: store i1 false, i1* [[NRVO]], align 1 3065 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3066 // CHECK-EH-03-NEXT: store i1 true, i1* [[NRVO]], align 1 3067 // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 3068 // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 3069 // CHECK-EH-03: nrvo.unused: 3070 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3071 // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] 3072 // CHECK-EH-03: nrvo.skipdtor: 3073 // CHECK-EH-03-NEXT: ret void 3074 // 3075 // CHECK-EH-11-LABEL: @_Z6test24v( 3076 // CHECK-EH-11-NEXT: entry: 3077 // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca i8*, align 4 3078 // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 3079 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = bitcast %class.X* [[AGG_RESULT:%.*]] to i8* 3080 // CHECK-EH-11-NEXT: store i8* [[TMP0]], i8** [[RESULT_PTR]], align 4 3081 // CHECK-EH-11-NEXT: store i1 false, i1* [[NRVO]], align 1 3082 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3083 // CHECK-EH-11-NEXT: store i1 true, i1* [[NRVO]], align 1 3084 // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, i1* [[NRVO]], align 1 3085 // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] 3086 // CHECK-EH-11: nrvo.unused: 3087 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 3088 // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] 3089 // CHECK-EH-11: nrvo.skipdtor: 3090 // CHECK-EH-11-NEXT: ret void 3091 // 3092 X test24() { // http://wg21.link/p2025r2#ex-20 3093 X x; 3094 if (&x == &OuterX) 3095 throw 0; 3096 return x; // NRVO happens 3097 } 3098 #endif 3099 3100 #ifdef CXX11 3101 template <bool B> 3102 X test25() { 3103 X x; 3104 if constexpr (B) { 3105 return x; // FIXME: NRVO could happen when B == true, but doesn't 3106 } else { 3107 return X(); 3108 } 3109 } 3110 3111 // CHECK-EH-11-LABEL: define linkonce_odr void @_Z6test25ILb1EE1Xv( 3112 // CHECK-EH-11-NEXT: entry: 3113 // CHECK-EH-11: [[X:%.*]] = alloca %class.X, 3114 // CHECK-EH-11: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3115 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) %{{.*}}, %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3116 // CHECK-EH-11-NEXT: to label %{{.*}} unwind label %{{.*}} 3117 3118 // CHECK-EH-11: invoke.cont: 3119 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3120 // CHECK-EH-11-NEXT: ret void 3121 3122 // CHECK-EH-11: lpad: 3123 // CHECK-EH-11-NEXT: landingpad { i8*, i32 } 3124 // CHECK-EH-11: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3125 // CHECK-EH-11-NEXT: br label %{{.*}} 3126 3127 // CHECK-EH-11: resume { i8*, i32 } % 3128 3129 // CHECK-EH-11-LABEL: define linkonce_odr void @_Z6test25ILb0EE1Xv( 3130 // CHECK-EH-11-NEXT: entry: 3131 // CHECK-EH-11: [[X:%.*]] = alloca %class.X, 3132 // CHECK-EH-11: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3133 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) %{{.*}}) 3134 // CHECK-EH-11-NEXT: to label %{{.*}} unwind label %{{.*}} 3135 3136 // CHECK-EH-11: invoke.cont: 3137 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3138 // CHECK-EH-11-NEXT: ret void 3139 3140 // CHECK-EH-11: lpad: 3141 // CHECK-EH-11-NEXT: landingpad { i8*, i32 } 3142 // CHECK-EH-11: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 3143 // CHECK-EH-11-NEXT: br label %{{.*}} 3144 3145 // CHECK-EH-11: resume { i8*, i32 } % 3146 3147 void test25instantiate() { 3148 test25<true>(); 3149 test25<false>(); 3150 } 3151 #endif 3152