146 lines · cpp
1// RUN: %clang_cc1 -triple armv7-unknown-linux-gnueabihf %s -o - -emit-llvm -O2 | FileCheck %s2 3// Stack should be reused when possible, no need to allocate two separate slots4// if they have disjoint lifetime.5 6// Sizes of objects are related to previously existed threshold of 32. In case7// of S_large stack size is rounded to 40 bytes.8 9// 32B10struct S_small {11 int a[8];12};13 14// 36B15struct S_large {16 int a[9];17};18 19// Helper class for lifetime scope absence testing20struct Combiner {21 S_large a, b;22 23 Combiner(S_large);24 Combiner f();25};26 27extern S_small foo_small();28extern S_large foo_large();29extern void bar_small(S_small*);30extern void bar_large(S_large*);31 32// Prevent mangling of function names.33extern "C" {34 35void small_rvoed_unnamed_temporary_object() {36// CHECK-LABEL: define{{.*}} void @small_rvoed_unnamed_temporary_object37// CHECK: call void @llvm.lifetime.start38// CHECK: call void @_Z9foo_smallv39// CHECK: call void @llvm.lifetime.end40// CHECK: call void @llvm.lifetime.start41// CHECK: call void @_Z9foo_smallv42// CHECK: call void @llvm.lifetime.end43 44 foo_small();45 foo_small();46}47 48void large_rvoed_unnamed_temporary_object() {49// CHECK-LABEL: define{{.*}} void @large_rvoed_unnamed_temporary_object50// CHECK: call void @llvm.lifetime.start51// CHECK: call void @_Z9foo_largev52// CHECK: call void @llvm.lifetime.end53// CHECK: call void @llvm.lifetime.start54// CHECK: call void @_Z9foo_largev55// CHECK: call void @llvm.lifetime.end56 57 foo_large();58 foo_large();59}60 61void small_rvoed_named_temporary_object() {62// CHECK-LABEL: define{{.*}} void @small_rvoed_named_temporary_object63// CHECK: call void @llvm.lifetime.start64// CHECK: call void @_Z9foo_smallv65// CHECK: call void @llvm.lifetime.end66// CHECK: call void @llvm.lifetime.start67// CHECK: call void @_Z9foo_smallv68// CHECK: call void @llvm.lifetime.end69 70 {71 S_small s = foo_small();72 }73 {74 S_small s = foo_small();75 }76}77 78void large_rvoed_named_temporary_object() {79// CHECK-LABEL: define{{.*}} void @large_rvoed_named_temporary_object80// CHECK: call void @llvm.lifetime.start81// CHECK: call void @_Z9foo_largev82// CHECK: call void @llvm.lifetime.end83// CHECK: call void @llvm.lifetime.start84// CHECK: call void @_Z9foo_largev85// CHECK: call void @llvm.lifetime.end86 87 {88 S_large s = foo_large();89 }90 {91 S_large s = foo_large();92 }93}94 95void small_auto_object() {96// CHECK-LABEL: define{{.*}} void @small_auto_object97// CHECK: call void @llvm.lifetime.start98// CHECK: call void @_Z9bar_smallP7S_small99// CHECK: call void @llvm.lifetime.end100// CHECK: call void @llvm.lifetime.start101// CHECK: call void @_Z9bar_smallP7S_small102// CHECK: call void @llvm.lifetime.end103 104 {105 S_small s;106 bar_small(&s);107 }108 {109 S_small s;110 bar_small(&s);111 }112}113 114void large_auto_object() {115// CHECK-LABEL: define{{.*}} void @large_auto_object116// CHECK: call void @llvm.lifetime.start117// CHECK: call void @_Z9bar_largeP7S_large118// CHECK: call void @llvm.lifetime.end119// CHECK: call void @llvm.lifetime.start120// CHECK: call void @_Z9bar_largeP7S_large121// CHECK: call void @llvm.lifetime.end122 123 {124 S_large s;125 bar_large(&s);126 }127 {128 S_large s;129 bar_large(&s);130 }131}132 133int large_combiner_test(S_large s) {134// CHECK-LABEL: define{{.*}} i32 @large_combiner_test135// CHECK: [[T2:%.*]] = alloca %struct.Combiner136// CHECK: [[T1:%.*]] = alloca %struct.Combiner137// CHECK: [[T3:%.*]] = call noundef ptr @_ZN8CombinerC1E7S_large(ptr {{[^,]*}} [[T1]], [9 x i32] %s.coerce)138// CHECK: call void @_ZN8Combiner1fEv(ptr dead_on_unwind nonnull writable sret(%struct.Combiner) align 4 [[T2]], ptr {{[^,]*}} [[T1]])139// CHECK: [[T5:%.*]] = load i32, ptr [[T2]]140// CHECK: ret i32 [[T5]]141 142 return Combiner(s).f().a.a[0];143}144 145}146