1 // REQUIRES: amdgpu-registered-target 2 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT 3 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT 4 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT 5 6 namespace { 7 8 static int ctorcalls; 9 static int dtorcalls; 10 11 struct A { 12 A() : i(0) { ctorcalls++; } 13 ~A() { dtorcalls++; } 14 int i; 15 16 friend const A& operator<<(const A& a, int n) { 17 return a; 18 } 19 }; 20 21 void g(int) { } 22 void g(const A&) { } 23 24 void f1(bool b) { 25 g(b ? A().i : 0); 26 g(b || A().i); 27 g(b && A().i); 28 g(b ? A() << 1 : A() << 2); 29 } 30 31 struct Checker { 32 Checker() { 33 f1(true); 34 f1(false); 35 } 36 }; 37 38 Checker c; 39 40 } 41 42 // CHECK-OPT-LABEL: define{{.*}} i32 @_Z12getCtorCallsv() 43 int getCtorCalls() { 44 // CHECK-OPT: ret i32 5 45 return ctorcalls; 46 } 47 48 // CHECK-OPT-LABEL: define{{.*}} i32 @_Z12getDtorCallsv() 49 int getDtorCalls() { 50 // CHECK-OPT: ret i32 5 51 return dtorcalls; 52 } 53 54 // CHECK-OPT-LABEL: define{{.*}} zeroext i1 @_Z7successv() 55 bool success() { 56 // CHECK-OPT: ret i1 true 57 return ctorcalls == dtorcalls; 58 } 59 60 struct X { ~X(); int f(); }; 61 int g(int, int, int); 62 // CHECK-LABEL: @_Z16lifetime_nontriv 63 int lifetime_nontriv(bool cond) { 64 // CHECK-NOOPT: store i1 false, 65 // CHECK-NOOPT: store i1 false, 66 // CHECK-NOOPT: store i1 false, 67 // CHECK-NOOPT: store i1 false, 68 // CHECK-NOOPT: store i1 false, 69 // CHECK-NOOPT: store i1 false, 70 // CHECK-NOOPT: br i1 71 // 72 // CHECK-NOOPT: call void @llvm.lifetime.start 73 // CHECK-NOOPT: store i1 true, 74 // CHECK-NOOPT: store i1 true, 75 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv( 76 // CHECK-NOOPT: call void @llvm.lifetime.start 77 // CHECK-NOOPT: store i1 true, 78 // CHECK-NOOPT: store i1 true, 79 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv( 80 // CHECK-NOOPT: call void @llvm.lifetime.start 81 // CHECK-NOOPT: store i1 true, 82 // CHECK-NOOPT: store i1 true, 83 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv( 84 // CHECK-NOOPT: call noundef i32 @_Z1giii( 85 // CHECK-NOOPT: br label 86 // 87 // CHECK-NOOPT: call noundef i32 @_Z1giii(i32 noundef 1, i32 noundef 2, i32 noundef 3) 88 // CHECK-NOOPT: br label 89 // 90 // CHECK-NOOPT: load i1, 91 // CHECK-NOOPT: br i1 92 // CHECK-NOOPT: call void @_ZN1XD1Ev( 93 // CHECK-NOOPT: br label 94 // 95 // CHECK-NOOPT: load i1, 96 // CHECK-NOOPT: br i1 97 // CHECK-NOOPT: call void @llvm.lifetime.end 98 // CHECK-NOOPT: br label 99 // 100 // CHECK-NOOPT: load i1, 101 // CHECK-NOOPT: br i1 102 // CHECK-NOOPT: call void @_ZN1XD1Ev( 103 // CHECK-NOOPT: br label 104 // 105 // CHECK-NOOPT: load i1, 106 // CHECK-NOOPT: br i1 107 // CHECK-NOOPT: call void @llvm.lifetime.end 108 // CHECK-NOOPT: br label 109 // 110 // CHECK-NOOPT: load i1, 111 // CHECK-NOOPT: br i1 112 // CHECK-NOOPT: call void @_ZN1XD1Ev( 113 // CHECK-NOOPT: br label 114 // 115 // CHECK-NOOPT: load i1, 116 // CHECK-NOOPT: br i1 117 // CHECK-NOOPT: call void @llvm.lifetime.end 118 // CHECK-NOOPT: br label 119 // 120 // CHECK-NOOPT: ret 121 122 // CHECK-OPT: br i1 123 // 124 // CHECK-OPT: call void @llvm.lifetime.start 125 // CHECK-OPT: call noundef i32 @_ZN1X1fEv( 126 // CHECK-OPT: call void @llvm.lifetime.start 127 // CHECK-OPT: call noundef i32 @_ZN1X1fEv( 128 // CHECK-OPT: call void @llvm.lifetime.start 129 // CHECK-OPT: call noundef i32 @_ZN1X1fEv( 130 // CHECK-OPT: call noundef i32 @_Z1giii( 131 // CHECK-OPT: call void @_ZN1XD1Ev( 132 // CHECK-OPT: call void @llvm.lifetime.end 133 // CHECK-OPT: call void @_ZN1XD1Ev( 134 // CHECK-OPT: call void @llvm.lifetime.end 135 // CHECK-OPT: call void @_ZN1XD1Ev( 136 // CHECK-OPT: call void @llvm.lifetime.end 137 // CHECK-OPT: br label 138 return cond ? g(X().f(), X().f(), X().f()) : g(1, 2, 3); 139 } 140 141 struct Y { int f(); }; 142 int g(int, int, int); 143 // CHECK-LABEL: @_Z13lifetime_triv 144 int lifetime_triv(bool cond) { 145 // CHECK-NOOPT: call void @llvm.lifetime.start 146 // CHECK-NOOPT: call void @llvm.lifetime.start 147 // CHECK-NOOPT: call void @llvm.lifetime.start 148 // CHECK-NOOPT: br i1 149 // 150 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv( 151 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv( 152 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv( 153 // CHECK-NOOPT: call noundef i32 @_Z1giii( 154 // CHECK-NOOPT: br label 155 // 156 // CHECK-NOOPT: call noundef i32 @_Z1giii(i32 noundef 1, i32 noundef 2, i32 noundef 3) 157 // CHECK-NOOPT: br label 158 // 159 // CHECK-NOOPT: call void @llvm.lifetime.end 160 // CHECK-NOOPT-NOT: br 161 // CHECK-NOOPT: call void @llvm.lifetime.end 162 // CHECK-NOOPT-NOT: br 163 // CHECK-NOOPT: call void @llvm.lifetime.end 164 // 165 // CHECK-NOOPT: ret 166 167 // FIXME: LLVM isn't smart enough to remove the lifetime markers from the 168 // g(1, 2, 3) path here. 169 170 // CHECK-OPT: call void @llvm.lifetime.start 171 // CHECK-OPT: call void @llvm.lifetime.start 172 // CHECK-OPT: call void @llvm.lifetime.start 173 // CHECK-OPT: br i1 174 // 175 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv( 176 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv( 177 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv( 178 // CHECK-OPT: call noundef i32 @_Z1giii( 179 // CHECK-OPT: br label 180 // 181 // CHECK-OPT: call void @llvm.lifetime.end 182 // CHECK-OPT: call void @llvm.lifetime.end 183 // CHECK-OPT: call void @llvm.lifetime.end 184 return cond ? g(Y().f(), Y().f(), Y().f()) : g(1, 2, 3); 185 } 186 187 struct Z { ~Z() {} int f(); }; 188 int g(int, int, int); 189 // CHECK-LABEL: @_Z22lifetime_nontriv_empty 190 int lifetime_nontriv_empty(bool cond) { 191 // CHECK-OPT: br i1 192 // 193 // CHECK-OPT: call void @llvm.lifetime.start 194 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv( 195 // CHECK-OPT: call void @llvm.lifetime.start 196 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv( 197 // CHECK-OPT: call void @llvm.lifetime.start 198 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv( 199 // CHECK-OPT: call noundef i32 @_Z1giii( 200 // CHECK-OPT: call void @llvm.lifetime.end 201 // CHECK-OPT: call void @llvm.lifetime.end 202 // CHECK-OPT: call void @llvm.lifetime.end 203 // CHECK-OPT: br label 204 return cond ? g(Z().f(), Z().f(), Z().f()) : g(1, 2, 3); 205 } 206