summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/nrvo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/nrvo.cpp')
-rw-r--r--test/CodeGenCXX/nrvo.cpp87
1 files changed, 68 insertions, 19 deletions
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 9ee5536..6181f0e 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
+// RUN: %clang_cc1 -emit-llvm -O1 -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
// Test code generation for the named return value optimization.
class X {
@@ -13,48 +13,97 @@ public:
// CHECK-EH: define void @_Z5test0v
X test0() {
X x;
- // CHECK-NOT: call void @_ZN1XD1Ev
- // CHECK: ret void
- // CHECK-EH: br label
- // CHECK-EH: call void @_ZN1XD1Ev
- // CHECK-EH: br label
- // CHECK-EH: invoke void @_ZN1XD1Ev
- // CHECK-EH: ret void
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
+
+ // CHECK-EH: call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
return x;
}
// CHECK: define void @_Z5test1b(
+// CHECK-EH: define void @_Z5test1b(
X test1(bool B) {
- // CHECK: call void @_ZN1XC1Ev
+ // CHECK: tail call void @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
X x;
- // CHECK-NOT: call void @_ZN1XD1Ev
- // CHECK: ret void
if (B)
return (x);
return x;
- // CHECK-EH: invoke void @_ZN1XD1Ev
+ // CHECK-EH: tail call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
}
// CHECK: define void @_Z5test2b
// CHECK-EH: define void @_Z5test2b
X test2(bool B) {
- // No NRVO
- // CHECK: call void @_ZN1XC1Ev
+ // No NRVO.
+
X x;
- // CHECK: call void @_ZN1XC1Ev
X y;
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
if (B)
return y;
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
return x;
+
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: call void @_ZN1XC1Ev
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call void @_ZN1XC1ERKS_
// CHECK: call void @_ZN1XD1Ev
// CHECK: call void @_ZN1XD1Ev
// CHECK: ret void
+
+ // The block ordering in the -fexceptions IR is unfortunate.
+
+ // CHECK-EH: call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
+ // -> %invoke.cont1, %lpad
+
+ // %invoke.cont1:
+ // CHECK-EH: br i1
+ // -> %if.then, %if.end
+
+ // %if.then: returning 'x'
+ // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad5
+
+ // %invoke.cont: rethrow block for %eh.cleanup.
+ // This really should be elsewhere in the function.
+ // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
+ // CHECK-EH-NEXT: unreachable
+
+ // %lpad: landing pad for ctor of 'y', dtor of 'y'
+ // CHECK-EH: call i8* @llvm.eh.exception()
+ // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH-NEXT: br label
+ // -> %eh.cleanup
+
+ // %invoke.cont2: normal cleanup for 'x'
+ // CHECK-EH: call void @_ZN1XD1Ev
+ // CHECK-EH-NEXT: ret void
+
+ // %lpad5: landing pad for return copy ctors, EH cleanup for 'y'
+ // CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %eh.cleanup, %terminate.lpad
+
+ // %if.end: returning 'y'
+ // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad5
+
+ // %cleanup: normal cleanup for 'y'
// CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %invoke.cont2, %lpad
+
+ // %eh.cleanup: EH cleanup for 'x'
// CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %invoke.cont, %terminate.lpad
+
+ // %terminate.lpad: terminate landing pad.
+ // CHECK-EH: call i8* @llvm.eh.exception()
+ // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH-NEXT: call void @_ZSt9terminatev()
+ // CHECK-EH-NEXT: unreachable
+
}
X test3(bool B) {
OpenPOWER on IntegriCloud