Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
clang/test/CodeGenCXX/nrvo.cpp
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6:[0-9]+]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5:[0-9]+]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test0() { // http://wg21.link/p2025r2#ex-2 | X test0() { // http://wg21.link/p2025r2#ex-2 | ||||
X x; | X x; | ||||
return x; // NRVO happens | return x; // NRVO happens | ||||
} | } | ||||
// CHECK-LABEL: @_Z5test1b( | // CHECK-LABEL: @_Z5test1b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
Show All 13 Lines | |||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
Show All 13 Lines | |||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test1(bool B) { | X test1(bool B) { | ||||
X x; | X x; | ||||
if (B) | if (B) | ||||
return (x); // NRVO happens | return (x); // NRVO happens | ||||
return x; // NRVO happens | return x; // NRVO happens | ||||
} | } | ||||
// CHECK-LABEL: @_Z5test2b( | // CHECK-LABEL: @_Z5test2b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 | // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
Show All 14 Lines | |||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | ||||
// CHECK-EH-03: invoke.cont2: | // CHECK-EH-03: invoke.cont2: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad1: | // CHECK-EH-03: lpad1: | ||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | // CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 | // CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] | ||||
// CHECK-EH-03: invoke.cont3: | // CHECK-EH-03: invoke.cont3: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont4: | // CHECK-EH-03: invoke.cont4: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: invoke.cont5: | |||||
// CHECK-EH-03-NEXT: br label [[EHCLEANUP]] | |||||
// CHECK-EH-03: ehcleanup: | // CHECK-EH-03: ehcleanup: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]] | |||||
// CHECK-EH-03: invoke.cont7: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL6:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL8]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL6]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP8]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP9]]) #[[ATTR6:[0-9]+]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z5test2b( | // CHECK-EH-11-LABEL: @_Z5test2b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 | // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | ||||
// CHECK-EH-11: invoke.cont2: | // CHECK-EH-11: invoke.cont2: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad1: | // CHECK-EH-11: lpad1: | ||||
// CHECK-EH-11-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 | // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EHCLEANUP]] | // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD1]] | ||||
// CHECK-EH-11: invoke.cont3: | // CHECK-EH-11: invoke.cont3: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: ehcleanup: | // CHECK-EH-11: ehcleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL5]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL5]] | ||||
// | // | ||||
Show All 9 Lines | |||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK: nrvo.unused: | // CHECK: nrvo.unused: | ||||
Show All 19 Lines | |||||
// CHECK-EH-03-NEXT: entry: | // CHECK-EH-03-NEXT: entry: | ||||
// CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
Show All 19 Lines | |||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] | ||||
// CHECK-EH-11: nrvo.unused3: | // CHECK-EH-11: nrvo.unused3: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR4]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR4]] | ||||
// CHECK-EH-11: nrvo.skipdtor4: | // CHECK-EH-11: nrvo.skipdtor4: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test3(bool B) { // http://wg21.link/p2025r2#ex-4 | X test3(bool B) { // http://wg21.link/p2025r2#ex-4 | ||||
if (B) { | if (B) { | ||||
Show All 12 Lines | |||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
Show All 24 Lines | |||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-03: nrvo.skipdtor: | // CHECK-EH-03: nrvo.skipdtor: | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-EH-03-NEXT: ] | // CHECK-EH-03-NEXT: ] | ||||
// CHECK-EH-03: cleanup.cont: | // CHECK-EH-03: cleanup.cont: | ||||
// CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR7:[0-9]+]] | // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR5:[0-9]+]] | ||||
// CHECK-EH-03-NEXT: call void @llvm.trap() | // CHECK-EH-03-NEXT: call void @llvm.trap() | ||||
// CHECK-EH-03-NEXT: unreachable | // CHECK-EH-03-NEXT: unreachable | ||||
// CHECK-EH-03: return: | // CHECK-EH-03: return: | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: unreachable: | // CHECK-EH-03: unreachable: | ||||
// CHECK-EH-03-NEXT: unreachable | // CHECK-EH-03-NEXT: unreachable | ||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z5test4b( | // CHECK-EH-11-LABEL: @_Z5test4b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-EH-11-NEXT: ] | // CHECK-EH-11-NEXT: ] | ||||
// CHECK-EH-11: cleanup.cont: | // CHECK-EH-11: cleanup.cont: | ||||
// CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @llvm.trap() | // CHECK-EH-11-NEXT: call void @llvm.trap() | ||||
// CHECK-EH-11-NEXT: unreachable | // CHECK-EH-11-NEXT: unreachable | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: unreachable: | // CHECK-EH-11: unreachable: | ||||
// CHECK-EH-11-NEXT: unreachable | // CHECK-EH-11-NEXT: unreachable | ||||
// | // | ||||
X test4(bool B) { | X test4(bool B) { | ||||
Show All 14 Lines | |||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_Z9may_throwv() | // CHECK-EH-03-NEXT: invoke void @_Z9may_throwv() | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: br label [[TRY_CONT:%.*]] | // CHECK-EH-03-NEXT: br label [[TRY_CONT:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: catch ptr @_ZTI1X | // CHECK-EH-03-NEXT: catch ptr @_ZTI1X | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CATCH_DISPATCH:%.*]] | // CHECK-EH-03-NEXT: br label [[CATCH_DISPATCH:%.*]] | ||||
// CHECK-EH-03: catch.dispatch: | // CHECK-EH-03: catch.dispatch: | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR7]] | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR5]] | ||||
// CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]] | // CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] | ||||
// CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] | // CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: catch: | // CHECK-EH-03: catch: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR7]] | // CHECK-EH-03-NEXT: [[TMP4:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR5]] | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP5]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: [[TMP5:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR5]] | ||||
// CHECK-EH-03: invoke.cont1: | |||||
// CHECK-EH-03-NEXT: [[TMP7:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR7]] | |||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | ||||
// CHECK-EH-03: invoke.cont3: | // CHECK-EH-03: invoke.cont2: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD3:%.*]] | ||||
// CHECK-EH-03: lpad2: | // CHECK-EH-03: lpad1: | ||||
// CHECK-EH-03-NEXT: [[TMP8:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP6:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP8]], 0 | // CHECK-EH-03-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP9]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP10:%.*]] = extractvalue { ptr, i32 } [[TMP8]], 1 | // CHECK-EH-03-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP10]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD]] | // CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] | ||||
// CHECK-EH-03: invoke.cont5: | // CHECK-EH-03: invoke.cont4: | ||||
// CHECK-EH-03-NEXT: call void @__cxa_end_catch() | // CHECK-EH-03-NEXT: call void @__cxa_end_catch() | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: lpad4: | // CHECK-EH-03: lpad3: | ||||
// CHECK-EH-03-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP9:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP12:%.*]] = extractvalue { ptr, i32 } [[TMP11]], 0 | // CHECK-EH-03-NEXT: [[TMP10:%.*]] = extractvalue { ptr, i32 } [[TMP9]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP12]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP10]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP13:%.*]] = extractvalue { ptr, i32 } [[TMP11]], 1 | // CHECK-EH-03-NEXT: [[TMP11:%.*]] = extractvalue { ptr, i32 } [[TMP9]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP13]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP11]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[EHCLEANUP:%.*]] | |||||
// CHECK-EH-03: invoke.cont6: | |||||
// CHECK-EH-03-NEXT: br label [[EHCLEANUP]] | // CHECK-EH-03-NEXT: br label [[EHCLEANUP]] | ||||
// CHECK-EH-03: ehcleanup: | // CHECK-EH-03: ehcleanup: | ||||
// CHECK-EH-03-NEXT: invoke void @__cxa_end_catch() | // CHECK-EH-03-NEXT: call unwindabort void @__cxa_end_catch() | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[TERMINATE_LPAD]] | |||||
// CHECK-EH-03: invoke.cont7: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME]] | ||||
// CHECK-EH-03: try.cont: | // CHECK-EH-03: try.cont: | ||||
// CHECK-EH-03-NEXT: call void @llvm.trap() | // CHECK-EH-03-NEXT: call void @llvm.trap() | ||||
// CHECK-EH-03-NEXT: unreachable | // CHECK-EH-03-NEXT: unreachable | ||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN8:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN5:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL9:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL6:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN8]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN5]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL10:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL9]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL7:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL6]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL10]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL7]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP14:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP15:%.*]] = extractvalue { ptr, i32 } [[TMP14]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP15]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z5test5v( | // CHECK-EH-11-LABEL: @_Z5test5v( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: invoke void @_Z9may_throwv() | // CHECK-EH-11-NEXT: invoke void @_Z9may_throwv() | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: br label [[TRY_CONT:%.*]] | // CHECK-EH-11-NEXT: br label [[TRY_CONT:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: catch ptr @_ZTI1X | // CHECK-EH-11-NEXT: catch ptr @_ZTI1X | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CATCH_DISPATCH:%.*]] | // CHECK-EH-11-NEXT: br label [[CATCH_DISPATCH:%.*]] | ||||
// CHECK-EH-11: catch.dispatch: | // CHECK-EH-11: catch.dispatch: | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR6]] | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP4]] | // CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] | ||||
// CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: catch: | // CHECK-EH-11: catch: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP5:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: [[TMP4:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP5]]) | // CHECK-EH-11-NEXT: call unwindabort void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[X]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-11-NEXT: [[TMP5:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR5]] | ||||
// CHECK-EH-11: invoke.cont1: | |||||
// CHECK-EH-11-NEXT: [[TMP7:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR6]] | |||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | ||||
// CHECK-EH-11: invoke.cont3: | // CHECK-EH-11: invoke.cont2: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @__cxa_end_catch() | // CHECK-EH-11-NEXT: call void @__cxa_end_catch() | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: lpad2: | // CHECK-EH-11: lpad1: | ||||
// CHECK-EH-11-NEXT: [[TMP8:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP6:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP8]], 0 | // CHECK-EH-11-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP9]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP10:%.*]] = extractvalue { ptr, i32 } [[TMP8]], 1 | // CHECK-EH-11-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP10]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: invoke void @__cxa_end_catch() | // CHECK-EH-11-NEXT: call unwindabort void @__cxa_end_catch() | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[TERMINATE_LPAD]] | |||||
// CHECK-EH-11: invoke.cont4: | |||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME]] | ||||
// CHECK-EH-11: try.cont: | // CHECK-EH-11: try.cont: | ||||
// CHECK-EH-11-NEXT: call void @llvm.trap() | // CHECK-EH-11-NEXT: call void @llvm.trap() | ||||
// CHECK-EH-11-NEXT: unreachable | // CHECK-EH-11-NEXT: unreachable | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN5:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN3:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL6:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL4:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN5]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN3]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL7:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL6]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL4]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL7]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL5]] | ||||
// CHECK-EH-11: terminate.lpad: | |||||
// CHECK-EH-11-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-11-NEXT: catch ptr null | |||||
// CHECK-EH-11-NEXT: [[TMP12:%.*]] = extractvalue { ptr, i32 } [[TMP11]], 0 | |||||
// CHECK-EH-11-NEXT: call void @__clang_call_terminate(ptr [[TMP12]]) #[[ATTR7:[0-9]+]] | |||||
// CHECK-EH-11-NEXT: unreachable | |||||
// | // | ||||
X test5() { // http://wg21.link/p2025r2#ex-14 | X test5() { // http://wg21.link/p2025r2#ex-14 | ||||
try { | try { | ||||
may_throw(); | may_throw(); | ||||
} catch (X x) { | } catch (X x) { | ||||
return x; // FIXME: NRVO could happen, but doesn't | return x; // FIXME: NRVO could happen, but doesn't | ||||
} | } | ||||
} | } | ||||
Show All 19 Lines | |||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | |||||
// CHECK-EH-03: invoke.cont1: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z5test6v( | // CHECK-EH-11-LABEL: @_Z5test6v( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 | // CHECK-EH-11-NEXT: [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[A]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | ||||
// | // | ||||
X test6() { | X test6() { | ||||
X a __attribute__((aligned(8))); | X a __attribute__((aligned(8))); | ||||
return a; // NRVO is impossible | return a; // NRVO is impossible | ||||
} | } | ||||
// CHECK-LABEL: @_Z5test7b( | // CHECK-LABEL: @_Z5test7b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK: nrvo.unused: | // CHECK: nrvo.unused: | ||||
Show All 10 Lines | |||||
// CHECK-EH-03-LABEL: @_Z5test7b( | // CHECK-EH-03-LABEL: @_Z5test7b( | ||||
// CHECK-EH-03-NEXT: entry: | // CHECK-EH-03-NEXT: entry: | ||||
// CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
Show All 10 Lines | |||||
// CHECK-EH-11-LABEL: @_Z5test7b( | // CHECK-EH-11-LABEL: @_Z5test7b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
Show All 10 Lines | |||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK: nrvo.unused: | // CHECK: nrvo.unused: | ||||
Show All 19 Lines | |||||
// CHECK-EH-03-NEXT: entry: | // CHECK-EH-03-NEXT: entry: | ||||
// CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
Show All 19 Lines | |||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.else: | // CHECK-EH-11: if.else: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL2:%.*]] = load i1, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL2]], label [[NRVO_SKIPDTOR4:%.*]], label [[NRVO_UNUSED3:%.*]] | ||||
// CHECK-EH-11: nrvo.unused3: | // CHECK-EH-11: nrvo.unused3: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR4]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR4]] | ||||
// CHECK-EH-11: nrvo.skipdtor4: | // CHECK-EH-11: nrvo.skipdtor4: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test8(bool b) { | X test8(bool b) { | ||||
if (b) { | if (b) { | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.else: | // CHECK: if.else: | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
Show All 9 Lines | |||||
// CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: if.else: | // CHECK-EH-03: if.else: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont1: | // CHECK-EH-03: invoke.cont1: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: invoke.cont2: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | |||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test10b( | // CHECK-EH-11-LABEL: @_Z6test10b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: if.else: | // CHECK-EH-11: if.else: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-11: invoke.cont1: | // CHECK-EH-11: invoke.cont1: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// | // | ||||
Show All 10 Lines | |||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
Show All 9 Lines | |||||
// CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-03-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont1: | // CHECK-EH-03: invoke.cont1: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: invoke.cont2: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | |||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test11b( | // CHECK-EH-11-LABEL: @_Z6test11b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-11: invoke.cont1: | // CHECK-EH-11: invoke.cont1: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// | // | ||||
Show All 12 Lines | |||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: br label [[DO_BODY:%.*]] | // CHECK-NEXT: br label [[DO_BODY:%.*]] | ||||
// CHECK: do.body: | // CHECK: do.body: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
Show All 25 Lines | |||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: br label [[DO_BODY:%.*]] | // CHECK-EH-03-NEXT: br label [[DO_BODY:%.*]] | ||||
// CHECK-EH-03: do.body: | // CHECK-EH-03: do.body: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
Show All 25 Lines | |||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: br label [[DO_BODY:%.*]] | // CHECK-EH-11-NEXT: br label [[DO_BODY:%.*]] | ||||
// CHECK-EH-11: do.body: | // CHECK-EH-11: do.body: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-11-NEXT: i32 2, label [[DO_END:%.*]] | // CHECK-EH-11-NEXT: i32 2, label [[DO_END:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-EH-11-NEXT: ] | // CHECK-EH-11-NEXT: ] | ||||
// CHECK-EH-11: do.end: | // CHECK-EH-11: do.end: | ||||
Show All 17 Lines | |||||
// CHECK-LABEL: @_Z6test13b( | // CHECK-LABEL: @_Z6test13b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: br label [[RETURN:%.*]] | // CHECK-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
Show All 10 Lines | |||||
// CHECK-EH-03-LABEL: @_Z6test13b( | // CHECK-EH-03-LABEL: @_Z6test13b( | ||||
// CHECK-EH-03-NEXT: entry: | // CHECK-EH-03-NEXT: entry: | ||||
// CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
Show All 10 Lines | |||||
// CHECK-EH-11-LABEL: @_Z6test13b( | // CHECK-EH-11-LABEL: @_Z6test13b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test13(bool b) { // http://wg21.link/p2025r2#ex-7 | X test13(bool b) { // http://wg21.link/p2025r2#ex-7 | ||||
if (b) | if (b) | ||||
return X(); | return X(); | ||||
X x; | X x; | ||||
return x; // FIXME: NRVO could happen, but doesn't | return x; // FIXME: NRVO could happen, but doesn't | ||||
} | } | ||||
// CHECK-LABEL: @_Z6test14b( | // CHECK-LABEL: @_Z6test14b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
Show All 18 Lines | |||||
// CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont1: | // CHECK-EH-03: invoke.cont1: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont2: | // CHECK-EH-03: invoke.cont2: | ||||
// CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-03: nrvo.skipdtor: | // CHECK-EH-03: nrvo.skipdtor: | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: invoke.cont3: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | |||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test14b( | // CHECK-EH-11-LABEL: @_Z6test14b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-11: invoke.cont1: | // CHECK-EH-11: invoke.cont1: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// | // | ||||
Show All 11 Lines | |||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-NEXT: call void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
Show All 18 Lines | |||||
// CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont1: | // CHECK-EH-03: invoke.cont1: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-03: invoke.cont2: | // CHECK-EH-03: invoke.cont2: | ||||
// CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-03: nrvo.skipdtor: | // CHECK-EH-03: nrvo.skipdtor: | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: invoke.cont3: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | |||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test15b( | // CHECK-EH-11-LABEL: @_Z6test15b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[LPAD]] | ||||
// CHECK-EH-11: invoke.cont1: | // CHECK-EH-11: invoke.cont1: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | ||||
// | // | ||||
Show All 17 Lines | |||||
// CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON]], ptr [[REF_TMP]], i32 0, i32 0 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON]], ptr [[REF_TMP]], i32 0, i32 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[X]], ptr [[TMP0]], align 4 | // CHECK-EH-11-NEXT: store ptr [[X]], ptr [[TMP0]], align 4 | ||||
// CHECK-EH-11-NEXT: invoke void @"_ZZ6test16vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) | // CHECK-EH-11-NEXT: invoke void @"_ZZ6test16vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: invoke void @_Z8ConsumeX1X(ptr noundef [[AGG_TMP]]) | // CHECK-EH-11-NEXT: invoke void @_Z8ConsumeX1X(ptr noundef [[AGG_TMP]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]] | ||||
// CHECK-EH-11: invoke.cont2: | // CHECK-EH-11: invoke.cont2: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[EHCLEANUP:%.*]] | ||||
// CHECK-EH-11: lpad1: | // CHECK-EH-11: lpad1: | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | // CHECK-EH-11-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP5]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1 | // CHECK-EH-11-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP6]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EHCLEANUP]] | // CHECK-EH-11-NEXT: br label [[EHCLEANUP]] | ||||
// CHECK-EH-11: ehcleanup: | // CHECK-EH-11: ehcleanup: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | ||||
// | // | ||||
Show All 13 Lines | |||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | // CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: br label [[IMPOSSIBLE:%.*]] | // CHECK-NEXT: br label [[IMPOSSIBLE:%.*]] | ||||
// CHECK: impossible: | // CHECK: impossible: | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 | // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 3 | ||||
// CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then1: | // CHECK: if.then1: | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: br label [[RETURN:%.*]] | // CHECK-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: br label [[IF_END2]] | // CHECK-NEXT: br label [[IF_END2]] | ||||
// CHECK: if.end2: | // CHECK: if.end2: | ||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]] | // CHECK-NEXT: br label [[WHILE_BODY:%.*]] | ||||
// CHECK: while.body: | // CHECK: while.body: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 | // CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 0 | ||||
// CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | // CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | ||||
// CHECK: if.then4: | // CHECK: if.then4: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end5: | // CHECK: if.end5: | ||||
// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 | // CHECK-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 1 | ||||
// CHECK-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | // CHECK-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | ||||
// CHECK: if.then7: | // CHECK: if.then7: | ||||
// CHECK-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
// CHECK: if.end8: | // CHECK: if.end8: | ||||
// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 | // CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 2 | ||||
// CHECK-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | // CHECK-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | ||||
// CHECK: if.then10: | // CHECK: if.then10: | ||||
// CHECK-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3:![0-9]+]] | // CHECK-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3:![0-9]+]] | ||||
// CHECK: if.end11: | // CHECK: if.end11: | ||||
// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 | // CHECK-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 3 | ||||
// CHECK-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | // CHECK-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | ||||
// CHECK: if.then13: | // CHECK: if.then13: | ||||
// CHECK-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
// CHECK: if.end14: | // CHECK: if.end14: | ||||
// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 | // CHECK-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 4 | ||||
// CHECK-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | // CHECK-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | ||||
// CHECK: if.then16: | // CHECK: if.then16: | ||||
// CHECK-NEXT: call void @exit(i32 noundef 1) #[[ATTR4]] | // CHECK-NEXT: call void @exit(i32 noundef 1) #[[ATTR4]] | ||||
// CHECK-NEXT: br label [[IF_END17]] | // CHECK-NEXT: br label [[IF_END17]] | ||||
// CHECK: if.end17: | // CHECK: if.end17: | ||||
// CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 | // CHECK-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 5 | ||||
// CHECK-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | // CHECK-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | ||||
// CHECK: if.then19: | // CHECK: if.then19: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
// CHECK: if.end20: | // CHECK: if.end20: | ||||
// CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
Show All 29 Lines | |||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | // CHECK-EH-03-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: br label [[IMPOSSIBLE:%.*]] | // CHECK-EH-03-NEXT: br label [[IMPOSSIBLE:%.*]] | ||||
// CHECK-EH-03: impossible: | // CHECK-EH-03: impossible: | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 | // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 3 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then1: | // CHECK-EH-03: if.then1: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: br label [[IF_END2]] | // CHECK-EH-03-NEXT: br label [[IF_END2]] | ||||
// CHECK-EH-03: if.end2: | // CHECK-EH-03: if.end2: | ||||
// CHECK-EH-03-NEXT: br label [[WHILE_BODY:%.*]] | // CHECK-EH-03-NEXT: br label [[WHILE_BODY:%.*]] | ||||
// CHECK-EH-03: while.body: | // CHECK-EH-03: while.body: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | ||||
// CHECK-EH-03: if.then4: | // CHECK-EH-03: if.then4: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: if.end5: | // CHECK-EH-03: if.end5: | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 | // CHECK-EH-03-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | ||||
// CHECK-EH-03: if.then7: | // CHECK-EH-03: if.then7: | ||||
// CHECK-EH-03-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: if.end8: | // CHECK-EH-03: if.end8: | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 | // CHECK-EH-03-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 2 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | ||||
// CHECK-EH-03: if.then10: | // CHECK-EH-03: if.then10: | ||||
// CHECK-EH-03-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: if.end11: | // CHECK-EH-03: if.end11: | ||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 | // CHECK-EH-03-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 3 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | ||||
// CHECK-EH-03: if.then13: | // CHECK-EH-03: if.then13: | ||||
// CHECK-EH-03-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: if.end14: | // CHECK-EH-03: if.end14: | ||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 | // CHECK-EH-03-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 4 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | ||||
// CHECK-EH-03: if.then16: | // CHECK-EH-03: if.then16: | ||||
// CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR7]] | // CHECK-EH-03-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] | ||||
// CHECK-EH-03-NEXT: br label [[IF_END17]] | // CHECK-EH-03-NEXT: br label [[IF_END17]] | ||||
// CHECK-EH-03: if.end17: | // CHECK-EH-03: if.end17: | ||||
// CHECK-EH-03-NEXT: [[TMP7:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 | // CHECK-EH-03-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 5 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | ||||
// CHECK-EH-03: if.then19: | // CHECK-EH-03: if.then19: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: if.end20: | // CHECK-EH-03: if.end20: | ||||
// CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
Show All 29 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | // CHECK-EH-11-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END2:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: br label [[IMPOSSIBLE:%.*]] | // CHECK-EH-11-NEXT: br label [[IMPOSSIBLE:%.*]] | ||||
// CHECK-EH-11: impossible: | // CHECK-EH-11: impossible: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 | // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 3 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then1: | // CHECK-EH-11: if.then1: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: br label [[IF_END2]] | // CHECK-EH-11-NEXT: br label [[IF_END2]] | ||||
// CHECK-EH-11: if.end2: | // CHECK-EH-11: if.end2: | ||||
// CHECK-EH-11-NEXT: br label [[WHILE_BODY:%.*]] | // CHECK-EH-11-NEXT: br label [[WHILE_BODY:%.*]] | ||||
// CHECK-EH-11: while.body: | // CHECK-EH-11: while.body: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[CMP3:%.*]] = icmp eq i32 [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] | ||||
// CHECK-EH-11: if.then4: | // CHECK-EH-11: if.then4: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: if.end5: | // CHECK-EH-11: if.end5: | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP3]], 1 | // CHECK-EH-11-NEXT: [[CMP6:%.*]] = icmp eq i32 [[TMP2]], 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_END8:%.*]] | ||||
// CHECK-EH-11: if.then7: | // CHECK-EH-11: if.then7: | ||||
// CHECK-EH-11-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 4, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: if.end8: | // CHECK-EH-11: if.end8: | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP4]], 2 | // CHECK-EH-11-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP3]], 2 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP9]], label [[IF_THEN10:%.*]], label [[IF_END11:%.*]] | ||||
// CHECK-EH-11: if.then10: | // CHECK-EH-11: if.then10: | ||||
// CHECK-EH-11-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 3, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3:![0-9]+]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]], !llvm.loop [[LOOP3:![0-9]+]] | ||||
// CHECK-EH-11: if.end11: | // CHECK-EH-11: if.end11: | ||||
// CHECK-EH-11-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP5]], 3 | // CHECK-EH-11-NEXT: [[CMP12:%.*]] = icmp eq i32 [[TMP4]], 3 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP12]], label [[IF_THEN13:%.*]], label [[IF_END14:%.*]] | ||||
// CHECK-EH-11: if.then13: | // CHECK-EH-11: if.then13: | ||||
// CHECK-EH-11-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 2, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: if.end14: | // CHECK-EH-11: if.end14: | ||||
// CHECK-EH-11-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP5:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP6]], 4 | // CHECK-EH-11-NEXT: [[CMP15:%.*]] = icmp eq i32 [[TMP5]], 4 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP15]], label [[IF_THEN16:%.*]], label [[IF_END17:%.*]] | ||||
// CHECK-EH-11: if.then16: | // CHECK-EH-11: if.then16: | ||||
// CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @exit(i32 noundef 1) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[IF_END17]] | // CHECK-EH-11-NEXT: br label [[IF_END17]] | ||||
// CHECK-EH-11: if.end17: | // CHECK-EH-11: if.end17: | ||||
// CHECK-EH-11-NEXT: [[TMP7:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP6:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP7]], 5 | // CHECK-EH-11-NEXT: [[CMP18:%.*]] = icmp eq i32 [[TMP6]], 5 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP18]], label [[IF_THEN19:%.*]], label [[IF_END20:%.*]] | ||||
// CHECK-EH-11: if.then19: | // CHECK-EH-11: if.then19: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: if.end20: | // CHECK-EH-11: if.end20: | ||||
// CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 1, label [[RETURN]] | // CHECK-EH-11-NEXT: i32 1, label [[RETURN]] | ||||
// CHECK-EH-11-NEXT: i32 4, label [[WHILE_END:%.*]] | // CHECK-EH-11-NEXT: i32 4, label [[WHILE_END:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 3, label [[WHILE_BODY]] | // CHECK-EH-11-NEXT: i32 3, label [[WHILE_BODY]] | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 | // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 | ||||
// CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP:%.*]] | // CHECK-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK: if.end: | // CHECK: if.end: | ||||
// CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP]] | // CHECK-NEXT: br label [[CLEANUP]] | ||||
// CHECK: cleanup: | // CHECK: cleanup: | ||||
// CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK: nrvo.unused: | // CHECK: nrvo.unused: | ||||
// CHECK-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]] | // CHECK-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR4]] | ||||
// CHECK-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK: nrvo.skipdtor: | // CHECK: nrvo.skipdtor: | ||||
// CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-NEXT: ] | // CHECK-NEXT: ] | ||||
// CHECK: cleanup.cont: | // CHECK: cleanup.cont: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO1]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO1]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP2]], 1 | // CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 1 | ||||
// CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | // CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | ||||
// CHECK: if.then3: | // CHECK: if.then3: | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO1]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO1]], align 1 | ||||
// CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP5:%.*]] | // CHECK-NEXT: br label [[CLEANUP5:%.*]] | ||||
// CHECK: if.end4: | // CHECK: if.end4: | ||||
// CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-NEXT: br label [[CLEANUP5]] | // CHECK-NEXT: br label [[CLEANUP5]] | ||||
Show All 33 Lines | |||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 | // CHECK-EH-03-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP]] | // CHECK-EH-03-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-03: cleanup: | // CHECK-EH-03: cleanup: | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-03: nrvo.skipdtor: | // CHECK-EH-03: nrvo.skipdtor: | ||||
// CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-03-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-EH-03-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-EH-03-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-EH-03-NEXT: ] | // CHECK-EH-03-NEXT: ] | ||||
// CHECK-EH-03: cleanup.cont: | // CHECK-EH-03: cleanup.cont: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO1]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | // CHECK-EH-03-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | ||||
// CHECK-EH-03: if.then3: | // CHECK-EH-03: if.then3: | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO1]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP5:%.*]] | // CHECK-EH-03-NEXT: br label [[CLEANUP5:%.*]] | ||||
// CHECK-EH-03: if.end4: | // CHECK-EH-03: if.end4: | ||||
// CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: br label [[CLEANUP5]] | // CHECK-EH-03-NEXT: br label [[CLEANUP5]] | ||||
Show All 33 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO1:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO11:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: store i32 [[I:%.*]], ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 | // CHECK-EH-11-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP]] | // CHECK-EH-11-NEXT: br label [[CLEANUP]] | ||||
// CHECK-EH-11: cleanup: | // CHECK-EH-11: cleanup: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST]], label [[UNREACHABLE:%.*]] [ | ||||
// CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: i32 1, label [[RETURN:%.*]] | ||||
// CHECK-EH-11-NEXT: ] | // CHECK-EH-11-NEXT: ] | ||||
// CHECK-EH-11: cleanup.cont: | // CHECK-EH-11: cleanup.cont: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = load i32, ptr [[I_ADDR]], align 4 | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | // CHECK-EH-11-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] | ||||
// CHECK-EH-11: if.then3: | // CHECK-EH-11: if.then3: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP5:%.*]] | // CHECK-EH-11-NEXT: br label [[CLEANUP5:%.*]] | ||||
// CHECK-EH-11: if.end4: | // CHECK-EH-11: if.end4: | ||||
// CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 0, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: br label [[CLEANUP5]] | // CHECK-EH-11-NEXT: br label [[CLEANUP5]] | ||||
// CHECK-EH-11: cleanup5: | // CHECK-EH-11: cleanup5: | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL6:%.*]] = load i1, ptr [[NRVO1]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL6:%.*]] = load i1, ptr [[NRVO1]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL6]], label [[NRVO_SKIPDTOR8:%.*]], label [[NRVO_UNUSED7:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL6]], label [[NRVO_SKIPDTOR8:%.*]], label [[NRVO_UNUSED7:%.*]] | ||||
// CHECK-EH-11: nrvo.unused7: | // CHECK-EH-11: nrvo.unused7: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR8]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR8]] | ||||
// CHECK-EH-11: nrvo.skipdtor8: | // CHECK-EH-11: nrvo.skipdtor8: | ||||
// CHECK-EH-11-NEXT: [[CLEANUP_DEST9:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[CLEANUP_DEST9:%.*]] = load i32, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST9]], label [[UNREACHABLE]] [ | // CHECK-EH-11-NEXT: switch i32 [[CLEANUP_DEST9]], label [[UNREACHABLE]] [ | ||||
// CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT10:%.*]] | // CHECK-EH-11-NEXT: i32 0, label [[CLEANUP_CONT10:%.*]] | ||||
// CHECK-EH-11-NEXT: i32 1, label [[RETURN]] | // CHECK-EH-11-NEXT: i32 1, label [[RETURN]] | ||||
// CHECK-EH-11-NEXT: ] | // CHECK-EH-11-NEXT: ] | ||||
// CHECK-EH-11: cleanup.cont10: | // CHECK-EH-11: cleanup.cont10: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO11]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO11]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO11]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO11]], align 1 | ||||
// CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 1, ptr [[CLEANUP_DEST_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL13:%.*]] = load i1, ptr [[NRVO11]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL13:%.*]] = load i1, ptr [[NRVO11]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL13]], label [[NRVO_SKIPDTOR15:%.*]], label [[NRVO_UNUSED14:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL13]], label [[NRVO_SKIPDTOR15:%.*]], label [[NRVO_UNUSED14:%.*]] | ||||
// CHECK-EH-11: nrvo.unused14: | // CHECK-EH-11: nrvo.unused14: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR15]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR15]] | ||||
// CHECK-EH-11: nrvo.skipdtor15: | // CHECK-EH-11: nrvo.skipdtor15: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: unreachable: | // CHECK-EH-11: unreachable: | ||||
// CHECK-EH-11-NEXT: unreachable | // CHECK-EH-11-NEXT: unreachable | ||||
// | // | ||||
Show All 19 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[L:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[L:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 4 | // CHECK-EH-11-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 4 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], ptr [[REF_TMP]], i32 0, i32 0 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], ptr [[REF_TMP]], i32 0, i32 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT]], ptr [[TMP1]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT]], ptr [[TMP0]], align 4 | ||||
// CHECK-EH-11-NEXT: invoke void @"_ZZ6test19vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[L]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) | // CHECK-EH-11-NEXT: invoke void @"_ZZ6test19vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[L]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[L]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[L]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
Show All 21 Lines | X test20() { // http://wg21.link/p2025r2#ex-18 | ||||
return x; // FIXME: NRVO could happen when B == false, but doesn't | return x; // FIXME: NRVO could happen when B == false, but doesn't | ||||
} | } | ||||
// CHECK-EH-11-LABEL: @_Z17test20instantiatev( | // CHECK-EH-11-LABEL: @_Z17test20instantiatev( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 | // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_Z6test20ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) | // CHECK-EH-11-NEXT: call void @_Z6test20ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @_Z6test20ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) | // CHECK-EH-11-NEXT: call void @_Z6test20ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
void test20instantiate() { | void test20instantiate() { | ||||
test20<true>(); | test20<true>(); | ||||
test20<false>(); | test20<false>(); | ||||
} | } | ||||
#endif | #endif | ||||
Show All 35 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
const volatile X test21() { // http://wg21.link/p2025r2#ex-19 | const volatile X test21() { // http://wg21.link/p2025r2#ex-19 | ||||
X x; | X x; | ||||
return x; // NRVO happens | return x; // NRVO happens | ||||
} | } | ||||
Show All 17 Lines | |||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | |||||
// CHECK-EH-03: invoke.cont1: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP4]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP5]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test22v( | // CHECK-EH-11-LABEL: @_Z6test22v( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[X]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | // CHECK-EH-11-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | ||||
// | // | ||||
X test22() { // http://wg21.link/p2025r2#ex-19 | X test22() { // http://wg21.link/p2025r2#ex-19 | ||||
volatile X x; | volatile X x; | ||||
return x; // NRVO is impossible | return x; // NRVO is impossible | ||||
} | } | ||||
// CHECK-LABEL: @_Z6test23b( | // CHECK-LABEL: @_Z6test23b( | ||||
// CHECK-NEXT: entry: | // CHECK-NEXT: entry: | ||||
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK: if.then: | // CHECK: if.then: | ||||
// CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK: nrvo.unused: | // CHECK: nrvo.unused: | ||||
Show All 15 Lines | |||||
// CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-03-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-03-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-03-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-03-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-03-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-03-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-03-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-03-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-03-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-03: if.then: | // CHECK-EH-03: if.then: | ||||
// CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-03-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-03-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-03: nrvo.unused: | // CHECK-EH-03: nrvo.unused: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-03-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-03: nrvo.skipdtor: | // CHECK-EH-03: nrvo.skipdtor: | ||||
// CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-03-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-03: if.end: | // CHECK-EH-03: if.end: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-03-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-03: invoke.cont: | // CHECK-EH-03: invoke.cont: | ||||
// CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: br label [[RETURN]] | // CHECK-EH-03-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-03: lpad: | // CHECK-EH-03: lpad: | ||||
// CHECK-EH-03-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-03-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-03-NEXT: cleanup | // CHECK-EH-03-NEXT: cleanup | ||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-03-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-03-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-03-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-03-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: invoke void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-03-NEXT: call unwindabort void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-03-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]] | |||||
// CHECK-EH-03: invoke.cont1: | |||||
// CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-03-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-03: return: | // CHECK-EH-03: return: | ||||
// CHECK-EH-03-NEXT: ret void | // CHECK-EH-03-NEXT: ret void | ||||
// CHECK-EH-03: eh.resume: | // CHECK-EH-03: eh.resume: | ||||
// CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-03-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-03-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-03-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
// CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] | // CHECK-EH-03-NEXT: resume { ptr, i32 } [[LPAD_VAL1]] | ||||
// CHECK-EH-03: terminate.lpad: | |||||
// CHECK-EH-03-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } | |||||
// CHECK-EH-03-NEXT: catch ptr null | |||||
// CHECK-EH-03-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 | |||||
// CHECK-EH-03-NEXT: call void @__clang_call_terminate(ptr [[TMP6]]) #[[ATTR6]] | |||||
// CHECK-EH-03-NEXT: unreachable | |||||
// | // | ||||
// CHECK-EH-11-LABEL: @_Z6test23b( | // CHECK-EH-11-LABEL: @_Z6test23b( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | // CHECK-EH-11-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[Y:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | // CHECK-EH-11-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 4 | ||||
// CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | // CHECK-EH-11-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | // CHECK-EH-11-NEXT: [[FROMBOOL:%.*]] = zext i1 [[B:%.*]] to i8 | ||||
// CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: store i8 [[FROMBOOL]], ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TMP1:%.*]] = load i8, ptr [[B_ADDR]], align 1 | // CHECK-EH-11-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 | ||||
// CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1 | // CHECK-EH-11-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 | ||||
// CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | // CHECK-EH-11-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | ||||
// CHECK-EH-11: if.then: | // CHECK-EH-11: if.then: | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | // CHECK-EH-11-NEXT: br label [[RETURN:%.*]] | ||||
// CHECK-EH-11: if.end: | // CHECK-EH-11: if.end: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | // CHECK-EH-11-NEXT: invoke void @_ZN1XC1ERVKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) | ||||
// CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | ||||
// CHECK-EH-11: invoke.cont: | // CHECK-EH-11: invoke.cont: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[RETURN]] | // CHECK-EH-11-NEXT: br label [[RETURN]] | ||||
// CHECK-EH-11: lpad: | // CHECK-EH-11: lpad: | ||||
// CHECK-EH-11-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | // CHECK-EH-11-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | ||||
// CHECK-EH-11-NEXT: cleanup | // CHECK-EH-11-NEXT: cleanup | ||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 | // CHECK-EH-11-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | ||||
// CHECK-EH-11-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 | // CHECK-EH-11-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | ||||
// CHECK-EH-11-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | // CHECK-EH-11-NEXT: br label [[EH_RESUME:%.*]] | ||||
// CHECK-EH-11: return: | // CHECK-EH-11: return: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// CHECK-EH-11: eh.resume: | // CHECK-EH-11: eh.resume: | ||||
// CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | // CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | // CHECK-EH-11-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 | ||||
// CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | // CHECK-EH-11-NEXT: [[LPAD_VAL1:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 | ||||
Show All 31 Lines | |||||
// CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | // CHECK-EH-11-NEXT: [[NRVO:%.*]] = alloca i1, align 1 | ||||
// CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 | ||||
// CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 false, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) | ||||
// CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | // CHECK-EH-11-NEXT: [[NRVO_VAL:%.*]] = load i1, ptr [[NRVO]], align 1 | ||||
// CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | // CHECK-EH-11-NEXT: br i1 [[NRVO_VAL]], label [[NRVO_SKIPDTOR:%.*]], label [[NRVO_UNUSED:%.*]] | ||||
// CHECK-EH-11: nrvo.unused: | // CHECK-EH-11: nrvo.unused: | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | // CHECK-EH-11-NEXT: br label [[NRVO_SKIPDTOR]] | ||||
// CHECK-EH-11: nrvo.skipdtor: | // CHECK-EH-11: nrvo.skipdtor: | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
X test24() { // http://wg21.link/p2025r2#ex-20 | X test24() { // http://wg21.link/p2025r2#ex-20 | ||||
X x; | X x; | ||||
if (&x == &OuterX) | if (&x == &OuterX) | ||||
throw 0; | throw 0; | ||||
Show All 12 Lines | X test25() { | ||||
} | } | ||||
} | } | ||||
// CHECK-EH-11-LABEL: @_Z17test25instantiatev( | // CHECK-EH-11-LABEL: @_Z17test25instantiatev( | ||||
// CHECK-EH-11-NEXT: entry: | // CHECK-EH-11-NEXT: entry: | ||||
// CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 | // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 | ||||
// CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 | // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 | ||||
// CHECK-EH-11-NEXT: call void @_Z6test25ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) | // CHECK-EH-11-NEXT: call void @_Z6test25ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: call void @_Z6test25ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) | // CHECK-EH-11-NEXT: call void @_Z6test25ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) | ||||
// CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]] | // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR5]] | ||||
// CHECK-EH-11-NEXT: ret void | // CHECK-EH-11-NEXT: ret void | ||||
// | // | ||||
void test25instantiate() { | void test25instantiate() { | ||||
test25<true>(); | test25<true>(); | ||||
test25<false>(); | test25<false>(); | ||||
} | } | ||||
#endif | #endif |