diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CodeGenCXX/nrvo.cpp | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CodeGenCXX/nrvo.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/nrvo.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp new file mode 100644 index 0000000..2feaf68 --- /dev/null +++ b/clang/test/CodeGenCXX/nrvo.cpp @@ -0,0 +1,161 @@ +// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s + +// Test code generation for the named return value optimization. +class X { +public: + X(); + X(const X&); + ~X(); +}; + +// CHECK: define void @_Z5test0v +// CHECK-EH: define void @_Z5test0v +X test0() { + X x; + // CHECK: call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: ret void + + // CHECK-EH: call {{.*}} @_ZN1XC1Ev + // CHECK-EH-NEXT: ret void + return x; +} + +// CHECK: define void @_Z5test1b( +// CHECK-EH: define void @_Z5test1b( +X test1(bool B) { + // CHECK: tail call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: ret void + X x; + if (B) + return (x); + return x; + // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev + // CHECK-EH-NEXT: ret void +} + +// CHECK: define void @_Z5test2b +// CHECK-EH: define void @_Z5test2b +X test2(bool B) { + // No NRVO. + + X x; + X y; + if (B) + return y; + return x; + + // CHECK: call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev + // CHECK: call {{.*}} @_ZN1XC1ERKS_ + // CHECK: call {{.*}} @_ZN1XC1ERKS_ + // CHECK: call {{.*}} @_ZN1XD1Ev + // CHECK: call {{.*}} @_ZN1XD1Ev + // CHECK: ret void + + // The block ordering in the -fexceptions IR is unfortunate. + + // CHECK-EH: call {{.*}} @_ZN1XC1Ev + // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev + // -> %invoke.cont, %lpad + + // %invoke.cont: + // CHECK-EH: br i1 + // -> %if.then, %if.end + + // %if.then: returning 'x' + // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ + // -> %cleanup, %lpad1 + + // %lpad: landing pad for ctor of 'y', dtor of 'y' + // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH-NEXT: cleanup + // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 + // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 + // CHECK-EH-NEXT: br label + // -> %eh.cleanup + + // %lpad1: landing pad for return copy ctors, EH cleanup for 'y' + // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev + // -> %eh.cleanup, %terminate.lpad + + // %if.end: returning 'y' + // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ + // -> %cleanup, %lpad1 + + // %cleanup: normal cleanup for 'y' + // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev + // -> %invoke.cont11, %lpad + + // %invoke.cont11: normal cleanup for 'x' + // CHECK-EH: call {{.*}} @_ZN1XD1Ev + // CHECK-EH-NEXT: ret void + + // %eh.cleanup: EH cleanup for 'x' + // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev + // -> %invoke.cont17, %terminate.lpad + + // %invoke.cont17: rethrow block for %eh.cleanup. + // This really should be elsewhere in the function. + // CHECK-EH: resume { i8*, i32 } + + // %terminate.lpad: terminate landing pad. + // CHECK-EH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH-NEXT: catch i8* null + // CHECK-EH-NEXT: call void @_ZSt9terminatev() + // CHECK-EH-NEXT: unreachable + +} + +X test3(bool B) { + // FIXME: We don't manage to apply NRVO here, although we could. + { + X y; + return y; + } + X x; + return x; +} + +extern "C" void exit(int) throw(); + +// CHECK: define void @_Z5test4b +X test4(bool B) { + { + // CHECK: tail call {{.*}} @_ZN1XC1Ev + X x; + // CHECK: br i1 + if (B) + return x; + } + // CHECK: tail call {{.*}} @_ZN1XD1Ev + // CHECK: tail call void @exit(i32 1) + exit(1); +} + +#ifdef __EXCEPTIONS +// CHECK-EH: define void @_Z5test5 +void may_throw(); +X test5() { + try { + may_throw(); + } catch (X x) { + // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ + // CHECK-EH: call void @__cxa_end_catch() + // CHECK-EH: ret void + return x; + } +} +#endif + +// rdar://problem/10430868 +// CHECK: define void @_Z5test6v +X test6() { + X a __attribute__((aligned(8))); + return a; + // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 + // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) + // CHECK-NEXT: ret void +} |