aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/nrvo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/nrvo.cpp')
-rw-r--r--test/CodeGenCXX/nrvo.cpp50
1 files changed, 47 insertions, 3 deletions
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index b83dd727e0bb..aad287dc3206 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -9,6 +9,14 @@ public:
~X();
};
+template<typename T> struct Y {
+ Y();
+ static Y f() {
+ Y y;
+ return y;
+ }
+};
+
// CHECK-LABEL: define void @_Z5test0v
// CHECK-EH-LABEL: define void @_Z5test0v
X test0() {
@@ -108,12 +116,17 @@ X test2(bool B) {
}
+// CHECK-LABEL: define void @_Z5test3b
X test3(bool B) {
- // FIXME: We don't manage to apply NRVO here, although we could.
- {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XC1Ev
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ if (B) {
X y;
return y;
}
+ // FIXME: we should NRVO this variable too.
X x;
return x;
}
@@ -156,9 +169,40 @@ X test6() {
return a;
// CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
// CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])
- // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]])
+ // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]])
// CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])
// CHECK-NEXT: ret void
}
+// CHECK-LABEL: define void @_Z5test7b
+X test7(bool b) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret
+ if (b) {
+ X x;
+ return x;
+ }
+ return X();
+}
+
+// CHECK-LABEL: define void @_Z5test8b
+X test8(bool b) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret
+ if (b) {
+ X x;
+ return x;
+ } else {
+ X y;
+ return y;
+ }
+}
+
+Y<int> test9() {
+ Y<int>::f();
+}
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
+// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
+
// CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }