1 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions 2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions 3 4 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s 5 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s 6 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s 7 // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s 8 // RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s 9 // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s 10 // RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s 11 // RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s 12 // RUN: FileCheck --check-prefix=CHECK9 --input-file=%t.ll %s 13 namespace test1 { 14 15 struct A { 16 A(); 17 virtual void foo(); 18 }; 19 20 struct B : A { 21 virtual void foo(); 22 }; 23 24 void g(A *a) { a->foo(); } 25 26 // CHECK1-LABEL: define void @_ZN5test14fooAEv() 27 // CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"* 28 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}} 29 // CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2) 30 // CHECK1: call void @llvm.assume(i1 %[[CMP]]) 31 // CHECK1-LABEL: } 32 33 void fooA() { 34 A a; 35 g(&a); 36 } 37 38 // CHECK1-LABEL: define void @_ZN5test14fooBEv() 39 // CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}}) 40 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}} 41 // CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2) 42 // CHECK1: call void @llvm.assume(i1 %[[CMP]]) 43 // CHECK1-LABEL: } 44 45 void fooB() { 46 B b; 47 g(&b); 48 } 49 // there should not be any assumes in the ctor that calls base ctor 50 // CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%"struct.test1::B"* 51 // CHECK1-NOT: @llvm.assume( 52 // CHECK1-LABEL: } 53 } 54 namespace test2 { 55 struct A { 56 A(); 57 virtual void foo(); 58 }; 59 60 struct B { 61 B(); 62 virtual void bar(); 63 }; 64 65 struct C : A, B { 66 C(); 67 virtual void foo(); 68 }; 69 void g(A *a) { a->foo(); } 70 void h(B *b) { b->bar(); } 71 72 // CHECK2-LABEL: define void @_ZN5test24testEv() 73 // CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"* 74 // CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}} 75 // CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 2) 76 // CHECK2: call void @llvm.assume(i1 %[[CMP]]) 77 78 // CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8* 79 // CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8 80 // CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8*** 81 // CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]] 82 // CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 5) 83 // CHECK2: call void @llvm.assume(i1 %[[CMP2]]) 84 85 // CHECK2: call void @_ZN5test21gEPNS_1AE( 86 // CHECK2-LABEL: } 87 88 void test() { 89 C c; 90 g(&c); 91 h(&c); 92 } 93 } 94 95 namespace test3 { 96 struct A { 97 A(); 98 }; 99 100 struct B : A { 101 B(); 102 virtual void foo(); 103 }; 104 105 struct C : virtual A, B { 106 C(); 107 virtual void foo(); 108 }; 109 void g(B *a) { a->foo(); } 110 111 // CHECK3-LABEL: define void @_ZN5test34testEv() 112 // CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"* 113 // CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5test31CE, i64 0, i64 3) 114 // CHECK3: call void @llvm.assume(i1 %[[CMP]]) 115 // CHECK3-LABLEL: } 116 void test() { 117 C c; 118 g(&c); 119 } 120 } // test3 121 122 namespace test4 { 123 struct A { 124 A(); 125 virtual void foo(); 126 }; 127 128 struct B : virtual A { 129 B(); 130 virtual void foo(); 131 }; 132 struct C : B { 133 C(); 134 virtual void foo(); 135 }; 136 137 void g(C *c) { c->foo(); } 138 139 // CHECK4-LABEL: define void @_ZN5test44testEv() 140 // CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"* 141 // CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}} 142 // CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4) 143 // CHECK4: call void @llvm.assume(i1 %[[CMP]] 144 145 // CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}} 146 // CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4) 147 // CHECK4: call void @llvm.assume(i1 %[[CMP2]]) 148 // CHECK4-LABEL: } 149 150 void test() { 151 C c; 152 g(&c); 153 } 154 } // test4 155 156 namespace testMS { 157 158 struct __declspec(novtable) S { 159 virtual void foo(); 160 }; 161 162 void g(S &s) { s.foo(); } 163 164 // if struct has novtable specifier, then we can't generate assumes 165 // CHECK-MS-LABEL: define void @"\01?test@testMS@@YAXXZ"() 166 // CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"\01??0S@testMS@@QAE@XZ"( 167 // CHECK-MS-NOT: @llvm.assume 168 // CHECK-MS-LABEL: } 169 170 void test() { 171 S s; 172 g(s); 173 } 174 175 } // testMS 176 177 namespace test6 { 178 struct A { 179 A(); 180 virtual void foo(); 181 virtual ~A() {} 182 }; 183 struct B : A { 184 B(); 185 }; 186 // FIXME: Because A's vtable is external, and no virtual functions are hidden, 187 // it's safe to generate assumption loads. 188 // CHECK6-LABEL: define void @_ZN5test61gEv() 189 // CHECK6: call void @_ZN5test61AC1Ev( 190 // CHECK6-NOT: call void @llvm.assume( 191 192 // We can't emit assumption loads for B, because if we would refer to vtable 193 // it would refer to functions that will not be able to find (like implicit 194 // inline destructor). 195 196 // CHECK6-LABEL: call void @_ZN5test61BC1Ev( 197 // CHECK6-NOT: call void @llvm.assume( 198 // CHECK6-LABEL: } 199 void g() { 200 A *a = new A; 201 B *b = new B; 202 } 203 } 204 205 namespace test7 { 206 // Because A's key function is defined here, vtable is generated in this TU 207 // CHECK7: @_ZTVN5test71AE = unnamed_addr constant 208 struct A { 209 A(); 210 virtual void foo(); 211 virtual void bar(); 212 }; 213 void A::foo() {} 214 215 // CHECK7-LABEL: define void @_ZN5test71gEv() 216 // CHECK7: call void @_ZN5test71AC1Ev( 217 // CHECK7: call void @llvm.assume( 218 // CHECK7-LABEL: } 219 void g() { 220 A *a = new A(); 221 a->bar(); 222 } 223 } 224 225 namespace test8 { 226 227 struct A { 228 virtual void foo(); 229 virtual void bar(); 230 }; 231 232 // CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr constant 233 struct B : A { 234 B(); 235 void foo(); 236 void bar(); 237 }; 238 239 // CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr constant 240 struct C : A { 241 C(); 242 void bar(); 243 void foo() {} 244 }; 245 inline void C::bar() {} 246 247 struct D : A { 248 D(); 249 void foo(); 250 void inline bar(); 251 }; 252 void D::bar() {} 253 254 // CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr constant 255 struct E : A { 256 E(); 257 }; 258 259 // CHECK8-LABEL: define void @_ZN5test81bEv() 260 // CHECK8: call void @llvm.assume( 261 // CHECK8-LABEL: } 262 void b() { 263 B b; 264 b.bar(); 265 } 266 267 // FIXME: C has inline virtual functions which prohibits as from generating 268 // assumption loads, but because vtable is generated in this TU (key function 269 // defined here) it would be correct to refer to it. 270 // CHECK8-LABEL: define void @_ZN5test81cEv() 271 // CHECK8-NOT: call void @llvm.assume( 272 // CHECK8-LABEL: } 273 void c() { 274 C c; 275 c.bar(); 276 } 277 278 // FIXME: We could generate assumption loads here. 279 // CHECK8-LABEL: define void @_ZN5test81dEv() 280 // CHECK8-NOT: call void @llvm.assume( 281 // CHECK8-LABEL: } 282 void d() { 283 D d; 284 d.bar(); 285 } 286 287 // CHECK8-LABEL: define void @_ZN5test81eEv() 288 // CHECK8: call void @llvm.assume( 289 // CHECK8-LABEL: } 290 void e() { 291 E e; 292 e.bar(); 293 } 294 } 295 296 namespace test9 { 297 298 struct S { 299 S(); 300 __attribute__((visibility("hidden"))) virtual void doStuff(); 301 }; 302 303 // CHECK9-LABEL: define void @_ZN5test94testEv() 304 // CHECK9-NOT: @llvm.assume( 305 // CHECK9: } 306 void test() { 307 S *s = new S(); 308 s->doStuff(); 309 delete s; 310 } 311 } 312 313