// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s

// Test code generation for the named return value optimization.
class X {
public:
  X();
  X(const X&);
  ~X();
};

template<typename T> struct Y {
  Y();
  static Y f() {
    Y y;
    return y;
  }
};

// CHECK-LABEL: @_Z5test0v(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-LABEL: @_Z5test0v(
// CHECK-EH-NEXT:  entry:
// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-NEXT:    ret void
//
X test0() {
  X x;

  return x;
}

// CHECK-LABEL: @_Z5test1b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-LABEL: @_Z5test1b(
// CHECK-EH-NEXT:  entry:
// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-NEXT:    ret void
//
X test1(bool B) {
  X x;
  if (B)
    return (x);
  return x;
}

// CHECK-LABEL: @_Z5test2b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
// CHECK-NEXT:    [[Y_X:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[Y_X]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR5]]
// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-03-LABEL: @_Z5test2b(
// CHECK-EH-03-NEXT:  entry:
// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-03-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-03:       invoke.cont:
// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]])
// CHECK-EH-03-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]]
// CHECK-EH-03:       lpad:
// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    br label [[EHCLEANUP:%.*]]
// CHECK-EH-03:       lpad1:
// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
// CHECK-EH-03-NEXT:    to label [[EHCLEANUP]] unwind label [[TERMINATE_LPAD:%.*]]
// CHECK-EH-03:       cleanup:
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]]
// CHECK-EH-03:       invoke.cont4:
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    ret void
// CHECK-EH-03:       ehcleanup:
// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP3]], [[LPAD]] ], [ [[TMP4]], [[LPAD1]] ]
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT9:%.*]] unwind label [[TERMINATE_LPAD]]
// CHECK-EH-03:       invoke.cont9:
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[DOTPN]]
// CHECK-EH-03:       terminate.lpad:
// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    catch i8* null
// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0
// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8:[0-9]+]]
// CHECK-EH-03-NEXT:    unreachable
//
// CHECK-EH-11-LABEL: @_Z5test2b(
// CHECK-EH-11-NEXT:  entry:
// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-11-NEXT:    [[Y:%.*]] = alloca [[CLASS_X]], align 1
// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[Y]], i32 0, i32 0
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]])
// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-11:       invoke.cont:
// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = select i1 [[B:%.*]], %class.X* [[Y]], %class.X* [[X]]
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP2]])
// CHECK-EH-11-NEXT:    to label [[CLEANUP:%.*]] unwind label [[LPAD1:%.*]]
// CHECK-EH-11:       lpad:
// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    cleanup
// CHECK-EH-11-NEXT:    br label [[EHCLEANUP:%.*]]
// CHECK-EH-11:       lpad1:
// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    cleanup
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    br label [[EHCLEANUP]]
// CHECK-EH-11:       cleanup:
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[Y]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    ret void
// CHECK-EH-11:       ehcleanup:
// CHECK-EH-11-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP4]], [[LPAD1]] ], [ [[TMP3]], [[LPAD]] ]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP1]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[DOTPN]]
//
X test2(bool B) {
  // No NRVO.

  X x;
  X y;
  if (B)
    return y;
  return x;
}

// CHECK-LABEL: @_Z5test3b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
// CHECK:       if.then:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
// CHECK-NEXT:    br label [[RETURN:%.*]]
// CHECK:       if.end:
// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR5]]
// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    br label [[RETURN]]
// CHECK:       return:
// CHECK-NEXT:    ret void
//
// CHECK-EH-03-LABEL: @_Z5test3b(
// CHECK-EH-03-NEXT:  entry:
// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
// CHECK-EH-03:       if.then:
// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-03-NEXT:    br label [[RETURN:%.*]]
// CHECK-EH-03:       if.end:
// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-03:       invoke.cont:
// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    br label [[RETURN]]
// CHECK-EH-03:       lpad:
// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* 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:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
// CHECK-EH-03:       return:
// CHECK-EH-03-NEXT:    ret void
// CHECK-EH-03:       terminate.lpad:
// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    catch i8* null
// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
// CHECK-EH-03-NEXT:    unreachable
//
// CHECK-EH-11-LABEL: @_Z5test3b(
// CHECK-EH-11-NEXT:  entry:
// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
// CHECK-EH-11:       if.then:
// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-11-NEXT:    br label [[RETURN:%.*]]
// CHECK-EH-11:       if.end:
// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-11:       invoke.cont:
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    br label [[RETURN]]
// CHECK-EH-11:       lpad:
// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    cleanup
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
// CHECK-EH-11:       return:
// CHECK-EH-11-NEXT:    ret void
//
X test3(bool B) {
  if (B) {
    X y;
    return y;
  }
  // FIXME: we should NRVO this variable too.
  X x;
  return x;
}

extern "C" void exit(int) throw();

// CHECK-LABEL: @_Z5test4b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
// CHECK-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
// CHECK:       nrvo.unused:
// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR5]]
// CHECK-NEXT:    call void @exit(i32 noundef 1) #[[ATTR5]]
// CHECK-NEXT:    unreachable
// CHECK:       return:
// CHECK-NEXT:    ret void
//
// CHECK-EH-03-LABEL: @_Z5test4b(
// CHECK-EH-03-NEXT:  entry:
// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-03-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
// CHECK-EH-03:       nrvo.unused:
// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]])
// CHECK-EH-03-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
// CHECK-EH-03-NEXT:    unreachable
// CHECK-EH-03:       return:
// CHECK-EH-03-NEXT:    ret void
//
// CHECK-EH-11-LABEL: @_Z5test4b(
// CHECK-EH-11-NEXT:  entry:
// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-11-NEXT:    br i1 [[B:%.*]], label [[RETURN:%.*]], label [[NRVO_UNUSED:%.*]]
// CHECK-EH-11:       nrvo.unused:
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @exit(i32 noundef 1) #[[ATTR7]]
// CHECK-EH-11-NEXT:    unreachable
// CHECK-EH-11:       return:
// CHECK-EH-11-NEXT:    ret void
//
X test4(bool B) {
  {
    X x;
    if (B)
      return x;
  }
  exit(1);
}

#ifdef __EXCEPTIONS
void may_throw();
// CHECK-EH-03-LABEL: @_Z5test5v(
// CHECK-EH-03-NEXT:  entry:
// CHECK-EH-03-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-03-NEXT:    invoke void @_Z9may_throwv()
// CHECK-EH-03-NEXT:    to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-03:       lpad:
// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)
// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1
// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]]
// CHECK-EH-03-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
// CHECK-EH-03-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
// CHECK-EH-03:       catch:
// CHECK-EH-03-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X*
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
// CHECK-EH-03:       invoke.cont1:
// CHECK-EH-03-NEXT:    [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]
// CHECK-EH-03:       invoke.cont3:
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD4:%.*]]
// CHECK-EH-03:       lpad2:
// CHECK-EH-03-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-03-NEXT:    to label [[EHCLEANUP:%.*]] unwind label [[TERMINATE_LPAD]]
// CHECK-EH-03:       invoke.cont5:
// CHECK-EH-03-NEXT:    call void @__cxa_end_catch()
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    ret void
// CHECK-EH-03:       lpad4:
// CHECK-EH-03-NEXT:    [[TMP9:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    br label [[EHCLEANUP]]
// CHECK-EH-03:       ehcleanup:
// CHECK-EH-03-NEXT:    [[DOTPN:%.*]] = phi { i8*, i32 } [ [[TMP9]], [[LPAD4]] ], [ [[TMP8]], [[LPAD2]] ]
// CHECK-EH-03-NEXT:    invoke 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:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    br label [[EH_RESUME]]
// CHECK-EH-03:       try.cont:
// CHECK-EH-03-NEXT:    unreachable
// CHECK-EH-03:       eh.resume:
// CHECK-EH-03-NEXT:    [[LPAD_VAL11_MERGED:%.*]] = phi { i8*, i32 } [ [[DOTPN]], [[INVOKE_CONT7]] ], [ [[TMP0]], [[LPAD]] ]
// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[LPAD_VAL11_MERGED]]
// CHECK-EH-03:       terminate.lpad:
// CHECK-EH-03-NEXT:    [[TMP10:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    catch i8* null
// CHECK-EH-03-NEXT:    [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP10]], 0
// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP11]]) #[[ATTR8]]
// CHECK-EH-03-NEXT:    unreachable
//
// CHECK-EH-11-LABEL: @_Z5test5v(
// CHECK-EH-11-NEXT:  entry:
// CHECK-EH-11-NEXT:    [[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
// CHECK-EH-11-NEXT:    invoke void @_Z9may_throwv()
// CHECK-EH-11-NEXT:    to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-11:       lpad:
// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    catch i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)
// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
// CHECK-EH-11-NEXT:    [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 1
// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*)) #[[ATTR7]]
// CHECK-EH-11-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
// CHECK-EH-11-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
// CHECK-EH-11:       catch:
// CHECK-EH-11-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[X]], i32 0, i32 0
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    [[TMP5:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[TMP1]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP5]] to %class.X*
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]], %class.X* noundef nonnull align 1 dereferenceable(1) [[TMP6]])
// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
// CHECK-EH-11:       invoke.cont1:
// CHECK-EH-11-NEXT:    [[TMP7:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP1]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[X]])
// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD2:%.*]]
// CHECK-EH-11:       invoke.cont3:
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @__cxa_end_catch()
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    ret void
// CHECK-EH-11:       lpad2:
// CHECK-EH-11-NEXT:    [[TMP8:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    cleanup
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[X]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    invoke 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:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP4]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    br label [[EH_RESUME]]
// CHECK-EH-11:       try.cont:
// CHECK-EH-11-NEXT:    unreachable
// CHECK-EH-11:       eh.resume:
// CHECK-EH-11-NEXT:    [[LPAD_VAL7_MERGED:%.*]] = phi { i8*, i32 } [ [[TMP8]], [[INVOKE_CONT4]] ], [ [[TMP0]], [[LPAD]] ]
// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[LPAD_VAL7_MERGED]]
// CHECK-EH-11:       terminate.lpad:
// CHECK-EH-11-NEXT:    [[TMP9:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    catch i8* null
// CHECK-EH-11-NEXT:    [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0
// CHECK-EH-11-NEXT:    call void @__clang_call_terminate(i8* [[TMP10]]) #[[ATTR8:[0-9]+]]
// CHECK-EH-11-NEXT:    unreachable
//
X test5() {
  try {
    may_throw();
  } catch (X x) {
    return x;
  }
}
#endif

// rdar://problem/10430868
// CHECK-LABEL: @_Z5test6v(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR5]]
// CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-03-LABEL: @_Z5test6v(
// CHECK-EH-03-NEXT:  entry:
// CHECK-EH-03-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
// CHECK-EH-03-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
// CHECK-EH-03-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
// CHECK-EH-03-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-03:       invoke.cont:
// CHECK-EH-03-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
// CHECK-EH-03-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    ret void
// CHECK-EH-03:       lpad:
// CHECK-EH-03-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    cleanup
// CHECK-EH-03-NEXT:    invoke void @_ZN1XD1Ev(%class.X* 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:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-03-NEXT:    resume { i8*, i32 } [[TMP1]]
// CHECK-EH-03:       terminate.lpad:
// CHECK-EH-03-NEXT:    [[TMP2:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-03-NEXT:    catch i8* null
// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
// CHECK-EH-03-NEXT:    call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
// CHECK-EH-03-NEXT:    unreachable
//
// CHECK-EH-11-LABEL: @_Z5test6v(
// CHECK-EH-11-NEXT:  entry:
// CHECK-EH-11-NEXT:    [[A:%.*]] = alloca [[CLASS_X:%.*]], align 8
// CHECK-EH-11-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* [[A]], i32 0, i32 0
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
// CHECK-EH-11-NEXT:    invoke void @_ZN1XC1ERKS_(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]], %class.X* noundef nonnull align 1 dereferenceable(1) [[A]])
// CHECK-EH-11-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-EH-11:       invoke.cont:
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    ret void
// CHECK-EH-11:       lpad:
// CHECK-EH-11-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
// CHECK-EH-11-NEXT:    cleanup
// CHECK-EH-11-NEXT:    call void @_ZN1XD1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7]]
// CHECK-EH-11-NEXT:    resume { i8*, i32 } [[TMP1]]
//
X test6() {
  X a __attribute__((aligned(8)));
  return a;
}

// CHECK-LABEL: @_Z5test7b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-LABEL: @_Z5test7b(
// CHECK-EH-NEXT:  entry:
// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-NEXT:    ret void
//
X test7(bool b) {
  if (b) {
    X x;
    return x;
  }
  return X();
}

// CHECK-LABEL: @_Z5test8b(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5]]
// CHECK-NEXT:    ret void
//
// CHECK-EH-LABEL: @_Z5test8b(
// CHECK-EH-NEXT:  entry:
// CHECK-EH-NEXT:    call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT:%.*]])
// CHECK-EH-NEXT:    ret void
//
X test8(bool b) {
  if (b) {
    X x;
    return x;
  } else {
    X y;
    return y;
  }
}

// CHECK-LABEL: @_Z5test9v(
// CHECK-NEXT:  entry:
// CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0
// CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR5]]
// CHECK-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]])
// CHECK-NEXT:    unreachable
//
// CHECK-EH-LABEL: @_Z5test9v(
// CHECK-EH-NEXT:  entry:
// CHECK-EH-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1
// CHECK-EH-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_Y]], %struct.Y* [[TMP]], i32 0, i32 0
// CHECK-EH-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[TMP0]]) #[[ATTR7:[0-9]+]]
// CHECK-EH-NEXT:    call void @_ZN1YIiE1fEv(%struct.Y* nonnull sret([[STRUCT_Y]]) align 1 [[TMP]])
// CHECK-EH-NEXT:    unreachable
//
Y<int> test9() {
  Y<int>::f();
}
