1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s 3 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s 4 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s 5 6 // Test code generation for the named return value optimization. 7 class X { 8 public: 9 X(); 10 X(const X&); 11 ~X(); 12 }; 13 14 template<typename T> struct Y { 15 Y(); 16 static Y f() { 17 Y y; 18 return y; 19 } 20 }; 21 22 // CHECK-LABEL: @_Z5test0v( 23 // CHECK-NEXT: entry: 24 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] 25 // CHECK-NEXT: ret void 26 // 27 // CHECK-EH-LABEL: @_Z5test0v( 28 // CHECK-EH-NEXT: entry: 29 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 30 // CHECK-EH-NEXT: ret void 31 // 32 X test0() { 33 X x; 34 35 return x; 36 } 37 38 // CHECK-LABEL: @_Z5test1b( 39 // CHECK-NEXT: entry: 40 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 41 // CHECK-NEXT: ret void 42 // 43 // CHECK-EH-LABEL: @_Z5test1b( 44 // CHECK-EH-NEXT: entry: 45 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 46 // CHECK-EH-NEXT: ret void 47 // 48 X test1(bool B) { 49 X x; 50 if (B) 51 return (x); 52 return x; 53 } 54 55 // CHECK-LABEL: @_Z5test2b( 56 // CHECK-NEXT: entry: 57 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 58 // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 59 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 60 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 61 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 62 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 63 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 64 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 65 // CHECK-NEXT: [[Y_X:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 66 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y_X]]) #[[ATTR5]] 67 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] 68 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]] 69 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 70 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 71 // CHECK-NEXT: ret void 72 // 73 // CHECK-EH-03-LABEL: @_Z5test2b( 74 // CHECK-EH-03-NEXT: entry: 75 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 76 // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 77 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 78 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 79 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 80 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 81 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 82 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 83 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 84 // CHECK-EH-03: invoke.cont: 85 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 86 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]]) 87 // CHECK-EH-03-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]] 88 // CHECK-EH-03: lpad: 89 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 90 // CHECK-EH-03-NEXT: cleanup 91 // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] 92 // CHECK-EH-03: lpad1: 93 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 94 // CHECK-EH-03-NEXT: cleanup 95 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 96 // CHECK-EH-03-NEXT: to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]] 97 // CHECK-EH-03: cleanup: 98 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 99 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] 100 // CHECK-EH-03: invoke.cont4: 101 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 102 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 103 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 104 // CHECK-EH-03-NEXT: ret void 105 // CHECK-EH-03: ehcleanup: 106 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD]] ], [ [[TMP4]], [[LPAD1]] ] 107 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 108 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 109 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[TERMINATE_LPAD]] 110 // CHECK-EH-03: invoke.cont9: 111 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 112 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[DOTPN]] 113 // CHECK-EH-03: terminate.lpad: 114 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } 115 // CHECK-EH-03-NEXT: catch i8* null 116 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0 117 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8:[0-9]+]] 118 // CHECK-EH-03-NEXT: unreachable 119 // 120 // CHECK-EH-11-LABEL: @_Z5test2b( 121 // CHECK-EH-11-NEXT: entry: 122 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 123 // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 124 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 125 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 126 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 127 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0 128 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 129 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) 130 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 131 // CHECK-EH-11: invoke.cont: 132 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]] 133 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]]) 134 // CHECK-EH-11-NEXT: to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]] 135 // CHECK-EH-11: lpad: 136 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 } 137 // CHECK-EH-11-NEXT: cleanup 138 // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] 139 // CHECK-EH-11: lpad1: 140 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } 141 // CHECK-EH-11-NEXT: cleanup 142 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 143 // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] 144 // CHECK-EH-11: cleanup: 145 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]] 146 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 147 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 148 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 149 // CHECK-EH-11-NEXT: ret void 150 // CHECK-EH-11: ehcleanup: 151 // CHECK-EH-11-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD1]] ], [ [[TMP3]], [[LPAD]] ] 152 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]] 153 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 154 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 155 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[DOTPN]] 156 // 157 X test2(bool B) { 158 // No NRVO. 159 160 X x; 161 X y; 162 if (B) 163 return y; 164 return x; 165 } 166 167 // CHECK-LABEL: @_Z5test3b( 168 // CHECK-NEXT: entry: 169 // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 170 // CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 171 // CHECK: if.then: 172 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 173 // CHECK-NEXT: br label [[RETURN:%.*]] 174 // CHECK: if.end: 175 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 176 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 177 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 178 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 179 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] 180 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 181 // CHECK-NEXT: br label [[RETURN]] 182 // CHECK: return: 183 // CHECK-NEXT: ret void 184 // 185 // CHECK-EH-03-LABEL: @_Z5test3b( 186 // CHECK-EH-03-NEXT: entry: 187 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 188 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 189 // CHECK-EH-03: if.then: 190 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 191 // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] 192 // CHECK-EH-03: if.end: 193 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 194 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 195 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 196 // 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]]) 197 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 198 // CHECK-EH-03: invoke.cont: 199 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 200 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 201 // CHECK-EH-03-NEXT: br label [[RETURN]] 202 // CHECK-EH-03: lpad: 203 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 204 // CHECK-EH-03-NEXT: cleanup 205 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 206 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 207 // CHECK-EH-03: invoke.cont1: 208 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 209 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 210 // CHECK-EH-03: return: 211 // CHECK-EH-03-NEXT: ret void 212 // CHECK-EH-03: terminate.lpad: 213 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 214 // CHECK-EH-03-NEXT: catch i8* null 215 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 216 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 217 // CHECK-EH-03-NEXT: unreachable 218 // 219 // CHECK-EH-11-LABEL: @_Z5test3b( 220 // CHECK-EH-11-NEXT: entry: 221 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 222 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 223 // CHECK-EH-11: if.then: 224 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 225 // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] 226 // CHECK-EH-11: if.end: 227 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 228 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 229 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 230 // 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]]) 231 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 232 // CHECK-EH-11: invoke.cont: 233 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 234 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 235 // CHECK-EH-11-NEXT: br label [[RETURN]] 236 // CHECK-EH-11: lpad: 237 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 238 // CHECK-EH-11-NEXT: cleanup 239 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 240 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 241 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 242 // CHECK-EH-11: return: 243 // CHECK-EH-11-NEXT: ret void 244 // 245 X test3(bool B) { 246 if (B) { 247 X y; 248 return y; 249 } 250 // FIXME: we should NRVO this variable too. 251 X x; 252 return x; 253 } 254 255 extern "C" void exit(int) throw(); 256 257 // CHECK-LABEL: @_Z5test4b( 258 // CHECK-NEXT: entry: 259 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 260 // CHECK-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 261 // CHECK: nrvo.unused: 262 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] 263 // CHECK-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] 264 // CHECK-NEXT: unreachable 265 // CHECK: return: 266 // CHECK-NEXT: ret void 267 // 268 // CHECK-EH-03-LABEL: @_Z5test4b( 269 // CHECK-EH-03-NEXT: entry: 270 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 271 // CHECK-EH-03-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 272 // CHECK-EH-03: nrvo.unused: 273 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) 274 // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 275 // CHECK-EH-03-NEXT: unreachable 276 // CHECK-EH-03: return: 277 // CHECK-EH-03-NEXT: ret void 278 // 279 // CHECK-EH-11-LABEL: @_Z5test4b( 280 // CHECK-EH-11-NEXT: entry: 281 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 282 // CHECK-EH-11-NEXT: br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]] 283 // CHECK-EH-11: nrvo.unused: 284 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]] 285 // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] 286 // CHECK-EH-11-NEXT: unreachable 287 // CHECK-EH-11: return: 288 // CHECK-EH-11-NEXT: ret void 289 // 290 X test4(bool B) { 291 { 292 X x; 293 if (B) 294 return x; 295 } 296 exit(1); 297 } 298 299 #ifdef __EXCEPTIONS 300 void may_throw(); 301 // CHECK-EH-03-LABEL: @_Z5test5v( 302 // CHECK-EH-03-NEXT: entry: 303 // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 304 // CHECK-EH-03-NEXT: invoke void @_Z9may_throwv() 305 // CHECK-EH-03-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]] 306 // CHECK-EH-03: lpad: 307 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 308 // CHECK-EH-03-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 309 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0 310 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1 311 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]] 312 // CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]] 313 // CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 314 // CHECK-EH-03: catch: 315 // CHECK-EH-03-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 316 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 317 // CHECK-EH-03-NEXT: [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]] 318 // CHECK-EH-03-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X* 319 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]]) 320 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 321 // CHECK-EH-03: invoke.cont1: 322 // CHECK-EH-03-NEXT: [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]] 323 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 324 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 325 // CHECK-EH-03: invoke.cont3: 326 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 327 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]] 328 // CHECK-EH-03: lpad2: 329 // CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 330 // CHECK-EH-03-NEXT: cleanup 331 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 332 // CHECK-EH-03-NEXT: to label [[EHCLEANUP:%.*]] unwind label [[TERMINATE_LPAD]] 333 // CHECK-EH-03: invoke.cont5: 334 // CHECK-EH-03-NEXT: call void @__cxa_end_catch() 335 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 336 // CHECK-EH-03-NEXT: ret void 337 // CHECK-EH-03: lpad4: 338 // CHECK-EH-03-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } 339 // CHECK-EH-03-NEXT: cleanup 340 // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] 341 // CHECK-EH-03: ehcleanup: 342 // CHECK-EH-03-NEXT: [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP9]], [[LPAD4]] ], [ [[TMP8]], [[LPAD2]] ] 343 // CHECK-EH-03-NEXT: invoke void @__cxa_end_catch() 344 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]] 345 // CHECK-EH-03: invoke.cont7: 346 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 347 // CHECK-EH-03-NEXT: br label [[EH_RESUME]] 348 // CHECK-EH-03: try.cont: 349 // CHECK-EH-03-NEXT: unreachable 350 // CHECK-EH-03: eh.resume: 351 // CHECK-EH-03-NEXT: [[LPAD_VAL11_MERGED:%.*]] = phi { i8*, i32 } [ [[DOTPN]], [[INVOKE_CONT7]] ], [ [[TMP0]], [[LPAD]] ] 352 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[LPAD_VAL11_MERGED]] 353 // CHECK-EH-03: terminate.lpad: 354 // CHECK-EH-03-NEXT: [[TMP10:%.*]] = landingpad { i8*, i32 } 355 // CHECK-EH-03-NEXT: catch i8* null 356 // CHECK-EH-03-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0 357 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP11]]) #[[ATTR8]] 358 // CHECK-EH-03-NEXT: unreachable 359 // 360 // CHECK-EH-11-LABEL: @_Z5test5v( 361 // CHECK-EH-11-NEXT: entry: 362 // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 363 // CHECK-EH-11-NEXT: invoke void @_Z9may_throwv() 364 // CHECK-EH-11-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]] 365 // CHECK-EH-11: lpad: 366 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 367 // CHECK-EH-11-NEXT: catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*) 368 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0 369 // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1 370 // CHECK-EH-11-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]] 371 // CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]] 372 // CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] 373 // CHECK-EH-11: catch: 374 // CHECK-EH-11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0 375 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 376 // CHECK-EH-11-NEXT: [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]] 377 // CHECK-EH-11-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X* 378 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]]) 379 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 380 // CHECK-EH-11: invoke.cont1: 381 // CHECK-EH-11-NEXT: [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]] 382 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) 383 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] 384 // CHECK-EH-11: invoke.cont3: 385 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 386 // CHECK-EH-11-NEXT: call void @__cxa_end_catch() 387 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 388 // CHECK-EH-11-NEXT: ret void 389 // CHECK-EH-11: lpad2: 390 // CHECK-EH-11-NEXT: [[TMP8:%.*]] = landingpad { i8*, i32 } 391 // CHECK-EH-11-NEXT: cleanup 392 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]] 393 // CHECK-EH-11-NEXT: invoke void @__cxa_end_catch() 394 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]] 395 // CHECK-EH-11: invoke.cont4: 396 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]] 397 // CHECK-EH-11-NEXT: br label [[EH_RESUME]] 398 // CHECK-EH-11: try.cont: 399 // CHECK-EH-11-NEXT: unreachable 400 // CHECK-EH-11: eh.resume: 401 // CHECK-EH-11-NEXT: [[LPAD_VAL7_MERGED:%.*]] = phi { i8*, i32 } [ [[TMP8]], [[INVOKE_CONT4]] ], [ [[TMP0]], [[LPAD]] ] 402 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[LPAD_VAL7_MERGED]] 403 // CHECK-EH-11: terminate.lpad: 404 // CHECK-EH-11-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } 405 // CHECK-EH-11-NEXT: catch i8* null 406 // CHECK-EH-11-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 407 // CHECK-EH-11-NEXT: call void @__clang_call_terminate(i8* [[TMP10]]) #[[ATTR8:[0-9]+]] 408 // CHECK-EH-11-NEXT: unreachable 409 // 410 X test5() { 411 try { 412 may_throw(); 413 } catch (X x) { 414 return x; 415 } 416 } 417 #endif 418 419 // rdar://problem/10430868 420 // CHECK-LABEL: @_Z5test6v( 421 // CHECK-NEXT: entry: 422 // CHECK-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 423 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 424 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 425 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 426 // CHECK-NEXT: call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 427 // CHECK-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] 428 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 429 // CHECK-NEXT: ret void 430 // 431 // CHECK-EH-03-LABEL: @_Z5test6v( 432 // CHECK-EH-03-NEXT: entry: 433 // CHECK-EH-03-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 434 // CHECK-EH-03-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 435 // CHECK-EH-03-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 436 // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 437 // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 438 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 439 // CHECK-EH-03: invoke.cont: 440 // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 441 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 442 // CHECK-EH-03-NEXT: ret void 443 // CHECK-EH-03: lpad: 444 // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 445 // CHECK-EH-03-NEXT: cleanup 446 // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 447 // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] 448 // CHECK-EH-03: invoke.cont1: 449 // CHECK-EH-03-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 450 // CHECK-EH-03-NEXT: resume { i8*, i32 } [[TMP1]] 451 // CHECK-EH-03: terminate.lpad: 452 // CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } 453 // CHECK-EH-03-NEXT: catch i8* null 454 // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 455 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]] 456 // CHECK-EH-03-NEXT: unreachable 457 // 458 // CHECK-EH-11-LABEL: @_Z5test6v( 459 // CHECK-EH-11-NEXT: entry: 460 // CHECK-EH-11-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 461 // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0 462 // CHECK-EH-11-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 463 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 464 // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) 465 // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 466 // CHECK-EH-11: invoke.cont: 467 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]] 468 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 469 // CHECK-EH-11-NEXT: ret void 470 // CHECK-EH-11: lpad: 471 // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } 472 // CHECK-EH-11-NEXT: cleanup 473 // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]] 474 // CHECK-EH-11-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]] 475 // CHECK-EH-11-NEXT: resume { i8*, i32 } [[TMP1]] 476 // 477 X test6() { 478 X a __attribute__((aligned(8))); 479 return a; 480 } 481 482 // CHECK-LABEL: @_Z5test7b( 483 // CHECK-NEXT: entry: 484 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 485 // CHECK-NEXT: ret void 486 // 487 // CHECK-EH-LABEL: @_Z5test7b( 488 // CHECK-EH-NEXT: entry: 489 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 490 // CHECK-EH-NEXT: ret void 491 // 492 X test7(bool b) { 493 if (b) { 494 X x; 495 return x; 496 } 497 return X(); 498 } 499 500 // CHECK-LABEL: @_Z5test8b( 501 // CHECK-NEXT: entry: 502 // CHECK-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]] 503 // CHECK-NEXT: ret void 504 // 505 // CHECK-EH-LABEL: @_Z5test8b( 506 // CHECK-EH-NEXT: entry: 507 // CHECK-EH-NEXT: call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) 508 // CHECK-EH-NEXT: ret void 509 // 510 X test8(bool b) { 511 if (b) { 512 X x; 513 return x; 514 } else { 515 X y; 516 return y; 517 } 518 } 519 520 // CHECK-LABEL: @_Z5test9v( 521 // CHECK-NEXT: entry: 522 // CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 523 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0 524 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]] 525 // CHECK-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]]) 526 // CHECK-NEXT: unreachable 527 // 528 // CHECK-EH-LABEL: @_Z5test9v( 529 // CHECK-EH-NEXT: entry: 530 // CHECK-EH-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 531 // CHECK-EH-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0 532 // CHECK-EH-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]] 533 // CHECK-EH-NEXT: call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]]) 534 // CHECK-EH-NEXT: unreachable 535 // 536 Y<int> test9() { 537 Y<int>::f(); 538 } 539