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