blob: 9726838508c174d058d6ba8f6bdde7db8ae6d73f [file] [log] [blame]
Serge Pavlovccdac232017-12-22 15:22:45 +00001//=== unittests/CodeGen/TBAAMetadataTest.cpp - Checks metadata generation -===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Serge Pavlovccdac232017-12-22 15:22:45 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "IRMatchers.h"
10#include "clang/AST/ASTConsumer.h"
11#include "clang/AST/ASTContext.h"
Reid Kleckner0f6959f2020-02-27 14:32:10 -080012#include "clang/Basic/SourceManager.h"
Serge Pavlovccdac232017-12-22 15:22:45 +000013#include "clang/CodeGen/ModuleBuilder.h"
14#include "clang/Frontend/CompilerInstance.h"
15#include "clang/Parse/ParseAST.h"
16#include "llvm/ADT/Triple.h"
Serge Pavlovccdac232017-12-22 15:22:45 +000017#include "llvm/IR/Constants.h"
Reid Kleckner0f6959f2020-02-27 14:32:10 -080018#include "llvm/IR/LLVMContext.h"
Serge Pavlovccdac232017-12-22 15:22:45 +000019#include "llvm/IR/Module.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include "gtest/gtest.h"
22#include <memory>
23
24using namespace llvm;
25
26namespace {
27
28struct TestCompiler {
29 LLVMContext Context;
30 clang::CompilerInstance compiler;
31 clang::CodeGenerator *CG = nullptr;
32 llvm::Module *M = nullptr;
33 unsigned PtrSize = 0;
34
35 void init(const char *TestProgram) {
36 compiler.createDiagnostics();
37 compiler.getCodeGenOpts().StructPathTBAA = 1;
38 compiler.getCodeGenOpts().OptimizationLevel = 1;
39
40 std::string TrStr = llvm::Triple::normalize(llvm::sys::getProcessTriple());
41 llvm::Triple Tr(TrStr);
42 Tr.setOS(Triple::Linux);
43 Tr.setVendor(Triple::VendorType::UnknownVendor);
44 Tr.setEnvironment(Triple::EnvironmentType::UnknownEnvironment);
45 compiler.getTargetOpts().Triple = Tr.getTriple();
46 compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
47 compiler.getDiagnostics(),
48 std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
49
50 const clang::TargetInfo &TInfo = compiler.getTarget();
51 PtrSize = TInfo.getPointerWidth(0) / 8;
52
53 compiler.createFileManager();
54 compiler.createSourceManager(compiler.getFileManager());
55 compiler.createPreprocessor(clang::TU_Prefix);
56
57 compiler.createASTContext();
58
59 CG = CreateLLVMCodeGen(
60 compiler.getDiagnostics(),
61 "main-module",
62 compiler.getHeaderSearchOpts(),
63 compiler.getPreprocessorOpts(),
64 compiler.getCodeGenOpts(),
65 Context);
66 compiler.setASTConsumer(std::unique_ptr<clang::ASTConsumer>(CG));
67
68 compiler.createSema(clang::TU_Prefix, nullptr);
69
70 clang::SourceManager &sm = compiler.getSourceManager();
71 sm.setMainFileID(sm.createFileID(
72 llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
73 }
74
75 const BasicBlock *compile() {
76 clang::ParseAST(compiler.getSema(), false, false);
77 M = CG->GetModule();
78
79 // Do not expect more than one function definition.
80 auto FuncPtr = M->begin();
81 for (; FuncPtr != M->end(); ++FuncPtr)
82 if (!FuncPtr->isDeclaration())
83 break;
84 assert(FuncPtr != M->end());
85 const llvm::Function &Func = *FuncPtr;
86 ++FuncPtr;
87 for (; FuncPtr != M->end(); ++FuncPtr)
88 if (!FuncPtr->isDeclaration())
89 break;
90 assert(FuncPtr == M->end());
91
92 // The function must consist of single basic block.
93 auto BBPtr = Func.begin();
94 assert(Func.begin() != Func.end());
95 const BasicBlock &BB = *BBPtr;
96 ++BBPtr;
97 assert(BBPtr == Func.end());
98
99 return &BB;
100 }
101};
102
103
104auto OmnipotentCharC = MMTuple(
105 MMString("omnipotent char"),
106 MMTuple(
107 MMString("Simple C/C++ TBAA")),
108 MConstInt(0, 64)
109);
110
111
112auto OmnipotentCharCXX = MMTuple(
113 MMString("omnipotent char"),
114 MMTuple(
115 MMString("Simple C++ TBAA")),
116 MConstInt(0, 64)
117);
118
119
120TEST(TBAAMetadataTest, BasicTypes) {
121 const char TestProgram[] = R"**(
122 void func(char *CP, short *SP, int *IP, long long *LP, void **VPP,
123 int **IPP) {
124 *CP = 4;
125 *SP = 11;
126 *IP = 601;
127 *LP = 604;
128 *VPP = CP;
129 *IPP = IP;
130 }
131 )**";
132
133 TestCompiler Compiler;
134 Compiler.compiler.getLangOpts().C11 = 1;
135 Compiler.init(TestProgram);
136 const BasicBlock *BB = Compiler.compile();
137
138 const Instruction *I = match(BB,
139 MInstruction(Instruction::Store,
140 MConstInt(4, 8),
141 MMTuple(
142 OmnipotentCharC,
143 MSameAs(0),
144 MConstInt(0))));
145 ASSERT_TRUE(I);
146
147 I = matchNext(I,
148 MInstruction(Instruction::Store,
149 MConstInt(11, 16),
150 MMTuple(
151 MMTuple(
152 MMString("short"),
153 OmnipotentCharC,
154 MConstInt(0)),
155 MSameAs(0),
156 MConstInt(0))));
157 ASSERT_TRUE(I);
158
159 I = matchNext(I,
160 MInstruction(Instruction::Store,
161 MConstInt(601, 32),
162 MMTuple(
163 MMTuple(
164 MMString("int"),
165 OmnipotentCharC,
166 MConstInt(0)),
167 MSameAs(0),
168 MConstInt(0))));
169 ASSERT_TRUE(I);
170
171 I = matchNext(I,
172 MInstruction(Instruction::Store,
173 MConstInt(604, 64),
174 MMTuple(
175 MMTuple(
176 MMString("long long"),
177 OmnipotentCharC,
178 MConstInt(0)),
179 MSameAs(0),
180 MConstInt(0))));
181 ASSERT_TRUE(I);
182
183 I = matchNext(I,
184 MInstruction(Instruction::Store,
185 MValType(Type::getInt8PtrTy(Compiler.Context)),
186 MMTuple(
187 MMTuple(
188 MMString("any pointer"),
189 OmnipotentCharC,
190 MConstInt(0)),
191 MSameAs(0),
192 MConstInt(0))));
193 ASSERT_TRUE(I);
194
195 I = matchNext(I,
196 MInstruction(Instruction::Store,
197 MValType(Type::getInt32PtrTy(Compiler.Context)),
198 MMTuple(
199 MMTuple(
200 MMString("any pointer"),
201 OmnipotentCharC,
202 MConstInt(0)),
203 MSameAs(0),
204 MConstInt(0))));
205 ASSERT_TRUE(I);
206}
207
208TEST(TBAAMetadataTest, CFields) {
209 const char TestProgram[] = R"**(
210 struct ABC {
211 short f16;
212 int f32;
213 long long f64;
214 unsigned short f16_2;
215 unsigned f32_2;
216 unsigned long long f64_2;
217 };
218
219 void func(struct ABC *A) {
220 A->f32 = 4;
221 A->f16 = 11;
222 A->f64 = 601;
223 A->f16_2 = 22;
224 A->f32_2 = 77;
225 A->f64_2 = 604;
226 }
227 )**";
228
229 TestCompiler Compiler;
230 Compiler.compiler.getLangOpts().C11 = 1;
231 Compiler.init(TestProgram);
232 const BasicBlock *BB = Compiler.compile();
233
234 auto StructABC = MMTuple(
235 MMString("ABC"),
236 MMTuple(
237 MMString("short"),
238 OmnipotentCharC,
239 MConstInt(0)),
240 MConstInt(0),
241 MMTuple(
242 MMString("int"),
243 OmnipotentCharC,
244 MConstInt(0)),
245 MConstInt(4),
246 MMTuple(
247 MMString("long long"),
248 OmnipotentCharC,
249 MConstInt(0)),
250 MConstInt(8),
251 MSameAs(1),
252 MConstInt(16),
253 MSameAs(3),
254 MConstInt(20),
255 MSameAs(5),
256 MConstInt(24));
257
258 const Instruction *I = match(BB,
259 MInstruction(Instruction::Store,
260 MConstInt(4, 32),
261 MMTuple(
262 StructABC,
263 MMTuple(
264 MMString("int"),
265 OmnipotentCharC,
266 MConstInt(0)),
267 MConstInt(4))));
268 ASSERT_TRUE(I);
269
270 I = matchNext(I,
271 MInstruction(Instruction::Store,
272 MConstInt(11, 16),
273 MMTuple(
274 StructABC,
275 MMTuple(
276 MMString("short"),
277 OmnipotentCharC,
278 MConstInt(0)),
279 MConstInt(0))));
280 ASSERT_TRUE(I);
281
282 I = matchNext(I,
283 MInstruction(Instruction::Store,
284 MConstInt(601, 64),
285 MMTuple(
286 StructABC,
287 MMTuple(
288 MMString("long long"),
289 OmnipotentCharC,
290 MConstInt(0)),
291 MConstInt(8))));
292 ASSERT_TRUE(I);
293
294 I = matchNext(I,
295 MInstruction(Instruction::Store,
296 MConstInt(22, 16),
297 MMTuple(
298 StructABC,
299 MMTuple(
300 MMString("short"),
301 OmnipotentCharC,
302 MConstInt(0)),
303 MConstInt(16))));
304 ASSERT_TRUE(I);
305
306 I = matchNext(I,
307 MInstruction(Instruction::Store,
308 MConstInt(77, 32),
309 MMTuple(
310 StructABC,
311 MMTuple(
312 MMString("int"),
313 OmnipotentCharC,
314 MConstInt(0)),
315 MConstInt(20))));
316 ASSERT_TRUE(I);
317
318 I = matchNext(I,
319 MInstruction(Instruction::Store,
320 MConstInt(604, 64),
321 MMTuple(
322 StructABC,
323 MMTuple(
324 MMString("long long"),
325 OmnipotentCharC,
326 MConstInt(0)),
327 MConstInt(24))));
328 ASSERT_TRUE(I);
329}
330
331TEST(TBAAMetadataTest, CTypedefFields) {
332 const char TestProgram[] = R"**(
333 typedef struct {
334 short f16;
335 int f32;
336 } ABC;
337 typedef struct {
338 short value_f16;
339 int value_f32;
340 } CDE;
341
342 void func(ABC *A, CDE *B) {
343 A->f32 = 4;
344 A->f16 = 11;
345 B->value_f32 = 44;
346 B->value_f16 = 111;
347 }
348 )**";
349
350 TestCompiler Compiler;
351 Compiler.compiler.getLangOpts().C11 = 1;
352 Compiler.init(TestProgram);
353 const BasicBlock *BB = Compiler.compile();
354
355 auto NamelessStruct = MMTuple(
356 MMString(""),
357 MMTuple(
358 MMString("short"),
359 OmnipotentCharC,
360 MConstInt(0)),
361 MConstInt(0),
362 MMTuple(
363 MMString("int"),
364 OmnipotentCharC,
365 MConstInt(0)),
366 MConstInt(4));
367
368 const Metadata *MetaABC = nullptr;
369 const Instruction *I = match(BB,
370 MInstruction(Instruction::Store,
371 MConstInt(4, 32),
372 MMTuple(
373 MMSave(MetaABC, NamelessStruct),
374 MMTuple(
375 MMString("int"),
376 OmnipotentCharC,
377 MConstInt(0)),
378 MConstInt(4))));
379 ASSERT_TRUE(I);
380
381 I = matchNext(I,
382 MInstruction(Instruction::Store,
383 MConstInt(11, 16),
384 MMTuple(
385 NamelessStruct,
386 MMTuple(
387 MMString("short"),
388 OmnipotentCharC,
389 MConstInt(0)),
390 MConstInt(0))));
391 ASSERT_TRUE(I);
392
393 const Metadata *MetaCDE = nullptr;
394 I = matchNext(I,
395 MInstruction(Instruction::Store,
396 MConstInt(44, 32),
397 MMTuple(
398 MMSave(MetaCDE, NamelessStruct),
399 MMTuple(
400 MMString("int"),
401 OmnipotentCharC,
402 MConstInt(0)),
403 MConstInt(4))));
404 ASSERT_TRUE(I);
405
406 I = matchNext(I,
407 MInstruction(Instruction::Store,
408 MConstInt(111, 16),
409 MMTuple(
410 NamelessStruct,
411 MMTuple(
412 MMString("short"),
413 OmnipotentCharC,
414 MConstInt(0)),
415 MConstInt(0))));
416 ASSERT_TRUE(I);
417
418 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are
419 // different structures and must be described by different descriptors.
420 //ASSERT_TRUE(MetaABC != MetaCDE);
421}
422
423TEST(TBAAMetadataTest, CTypedefFields2) {
424 const char TestProgram[] = R"**(
425 typedef struct {
426 short f16;
427 int f32;
428 } ABC;
429 typedef struct {
430 short f16;
431 int f32;
432 } CDE;
433
434 void func(ABC *A, CDE *B) {
435 A->f32 = 4;
436 A->f16 = 11;
437 B->f32 = 44;
438 B->f16 = 111;
439 }
440 )**";
441
442 TestCompiler Compiler;
443 Compiler.compiler.getLangOpts().C11 = 1;
444 Compiler.init(TestProgram);
445 const BasicBlock *BB = Compiler.compile();
446
447 auto NamelessStruct = MMTuple(
448 MMString(""),
449 MMTuple(
450 MMString("short"),
451 OmnipotentCharC,
452 MConstInt(0)),
453 MConstInt(0),
454 MMTuple(
455 MMString("int"),
456 OmnipotentCharC,
457 MConstInt(0)),
458 MConstInt(4));
459
460 const Metadata *MetaABC = nullptr;
461 const Instruction *I = match(BB,
462 MInstruction(Instruction::Store,
463 MConstInt(4, 32),
464 MMTuple(
465 MMSave(MetaABC, NamelessStruct),
466 MMTuple(
467 MMString("int"),
468 OmnipotentCharC,
469 MConstInt(0)),
470 MConstInt(4))));
471 ASSERT_TRUE(I);
472
473 I = matchNext(I,
474 MInstruction(Instruction::Store,
475 MConstInt(11, 16),
476 MMTuple(
477 NamelessStruct,
478 MMTuple(
479 MMString("short"),
480 OmnipotentCharC,
481 MConstInt(0)),
482 MConstInt(0))));
483 ASSERT_TRUE(I);
484
485 const Metadata *MetaCDE = nullptr;
486 I = matchNext(I,
487 MInstruction(Instruction::Store,
488 MConstInt(44, 32),
489 MMTuple(
490 MMSave(MetaCDE, NamelessStruct),
491 MMTuple(
492 MMString("int"),
493 OmnipotentCharC,
494 MConstInt(0)),
495 MConstInt(4))));
496 ASSERT_TRUE(I);
497
498 I = matchNext(I,
499 MInstruction(Instruction::Store,
500 MConstInt(111, 16),
501 MMTuple(
502 NamelessStruct,
503 MMTuple(
504 MMString("short"),
505 OmnipotentCharC,
506 MConstInt(0)),
507 MConstInt(0))));
508 ASSERT_TRUE(I);
509
510 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are
511 // different structures, although they have the same field sequence. They must
512 // be described by different descriptors.
513 //ASSERT_TRUE(MetaABC != MetaCDE);
514}
515
516TEST(TBAAMetadataTest, CTypedefFields3) {
517 const char TestProgram[] = R"**(
518 typedef struct {
519 short f16;
520 int f32;
521 } ABC;
522 typedef struct {
523 int f32;
524 short f16;
525 } CDE;
526
527 void func(ABC *A, CDE *B) {
528 A->f32 = 4;
529 A->f16 = 11;
530 B->f32 = 44;
531 B->f16 = 111;
532 }
533 )**";
534
535 TestCompiler Compiler;
536 Compiler.compiler.getLangOpts().C11 = 1;
537 Compiler.init(TestProgram);
538 const BasicBlock *BB = Compiler.compile();
539
540 auto NamelessStruct1 = MMTuple(
541 MMString(""),
542 MMTuple(
543 MMString("short"),
544 OmnipotentCharC,
545 MConstInt(0)),
546 MConstInt(0),
547 MMTuple(
548 MMString("int"),
549 OmnipotentCharC,
550 MConstInt(0)),
551 MConstInt(4));
552
553 auto NamelessStruct2 = MMTuple(
554 MMString(""),
555 MMTuple(
556 MMString("int"),
557 OmnipotentCharC,
558 MConstInt(0)),
559 MConstInt(0),
560 MMTuple(
561 MMString("short"),
562 OmnipotentCharC,
563 MConstInt(0)),
564 MConstInt(4));
565
566 const Instruction *I = match(BB,
567 MInstruction(Instruction::Store,
568 MConstInt(4, 32),
569 MMTuple(
570 NamelessStruct1,
571 MMTuple(
572 MMString("int"),
573 OmnipotentCharC,
574 MConstInt(0)),
575 MConstInt(4))));
576 ASSERT_TRUE(I);
577
578 I = matchNext(I,
579 MInstruction(Instruction::Store,
580 MConstInt(11, 16),
581 MMTuple(
582 NamelessStruct1,
583 MMTuple(
584 MMString("short"),
585 OmnipotentCharC,
586 MConstInt(0)),
587 MConstInt(0))));
588 ASSERT_TRUE(I);
589
590 I = matchNext(I,
591 MInstruction(Instruction::Store,
592 MConstInt(44, 32),
593 MMTuple(
594 NamelessStruct2,
595 MMTuple(
596 MMString("int"),
597 OmnipotentCharC,
598 MConstInt(0)),
599 MConstInt(0))));
600 ASSERT_TRUE(I);
601
602 I = matchNext(I,
603 MInstruction(Instruction::Store,
604 MConstInt(111, 16),
605 MMTuple(
606 NamelessStruct2,
607 MMTuple(
608 MMString("short"),
609 OmnipotentCharC,
610 MConstInt(0)),
611 MConstInt(4))));
612 ASSERT_TRUE(I);
613}
614
615TEST(TBAAMetadataTest, CXXFields) {
616 const char TestProgram[] = R"**(
617 struct ABC {
618 short f16;
619 int f32;
620 long long f64;
621 unsigned short f16_2;
622 unsigned f32_2;
623 unsigned long long f64_2;
624 };
625
626 void func(struct ABC *A) {
627 A->f32 = 4;
628 A->f16 = 11;
629 A->f64 = 601;
630 A->f16_2 = 22;
631 A->f32_2 = 77;
632 A->f64_2 = 604;
633 }
634 )**";
635
636 TestCompiler Compiler;
637 Compiler.compiler.getLangOpts().CPlusPlus = 1;
638 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
639 Compiler.init(TestProgram);
640 const BasicBlock *BB = Compiler.compile();
641
642 auto StructABC = MMTuple(
643 MMString("_ZTS3ABC"),
644 MMTuple(
645 MMString("short"),
646 OmnipotentCharCXX,
647 MConstInt(0)),
648 MConstInt(0),
649 MMTuple(
650 MMString("int"),
651 OmnipotentCharCXX,
652 MConstInt(0)),
653 MConstInt(4),
654 MMTuple(
655 MMString("long long"),
656 OmnipotentCharCXX,
657 MConstInt(0)),
658 MConstInt(8),
659 MSameAs(1),
660 MConstInt(16),
661 MSameAs(3),
662 MConstInt(20),
663 MSameAs(5),
664 MConstInt(24));
665
666 const Instruction *I = match(BB,
667 MInstruction(Instruction::Store,
668 MConstInt(4, 32),
669 MMTuple(
670 StructABC,
671 MMTuple(
672 MMString("int"),
673 OmnipotentCharCXX,
674 MConstInt(0)),
675 MConstInt(4))));
676 ASSERT_TRUE(I);
677
678 I = matchNext(I,
679 MInstruction(Instruction::Store,
680 MConstInt(11, 16),
681 MMTuple(
682 StructABC,
683 MMTuple(
684 MMString("short"),
685 OmnipotentCharCXX,
686 MConstInt(0)),
687 MConstInt(0))));
688 ASSERT_TRUE(I);
689
690 I = matchNext(I,
691 MInstruction(Instruction::Store,
692 MConstInt(601, 64),
693 MMTuple(
694 StructABC,
695 MMTuple(
696 MMString("long long"),
697 OmnipotentCharCXX,
698 MConstInt(0)),
699 MConstInt(8))));
700 ASSERT_TRUE(I);
701
702 I = matchNext(I,
703 MInstruction(Instruction::Store,
704 MConstInt(22, 16),
705 MMTuple(
706 StructABC,
707 MMTuple(
708 MMString("short"),
709 OmnipotentCharCXX,
710 MConstInt(0)),
711 MConstInt(16))));
712 ASSERT_TRUE(I);
713
714 I = matchNext(I,
715 MInstruction(Instruction::Store,
716 MConstInt(77, 32),
717 MMTuple(
718 StructABC,
719 MMTuple(
720 MMString("int"),
721 OmnipotentCharCXX,
722 MConstInt(0)),
723 MConstInt(20))));
724 ASSERT_TRUE(I);
725
726 I = matchNext(I,
727 MInstruction(Instruction::Store,
728 MConstInt(604, 64),
729 MMTuple(
730 StructABC,
731 MMTuple(
732 MMString("long long"),
733 OmnipotentCharCXX,
734 MConstInt(0)),
735 MConstInt(24))));
736 ASSERT_TRUE(I);
737}
738
739TEST(TBAAMetadataTest, CXXTypedefFields) {
740 const char TestProgram[] = R"**(
741 typedef struct {
742 short f16;
743 int f32;
744 } ABC;
745 typedef struct {
746 short value_f16;
747 int value_f32;
748 } CDE;
749
750 void func(ABC *A, CDE *B) {
751 A->f32 = 4;
752 A->f16 = 11;
753 B->value_f32 = 44;
754 B->value_f16 = 111;
755 }
756 )**";
757
758 TestCompiler Compiler;
759 Compiler.compiler.getLangOpts().CPlusPlus = 1;
760 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
761 Compiler.init(TestProgram);
762 const BasicBlock *BB = Compiler.compile();
763
764 auto StructABC = MMTuple(
765 MMString("_ZTS3ABC"),
766 MMTuple(
767 MMString("short"),
768 OmnipotentCharCXX,
769 MConstInt(0)),
770 MConstInt(0),
771 MMTuple(
772 MMString("int"),
773 OmnipotentCharCXX,
774 MConstInt(0)),
775 MConstInt(4));
776
777 auto StructCDE = MMTuple(
778 MMString("_ZTS3CDE"),
779 MMTuple(
780 MMString("short"),
781 OmnipotentCharCXX,
782 MConstInt(0)),
783 MConstInt(0),
784 MMTuple(
785 MMString("int"),
786 OmnipotentCharCXX,
787 MConstInt(0)),
788 MConstInt(4));
789
790 const Instruction *I = match(BB,
791 MInstruction(Instruction::Store,
792 MConstInt(4, 32),
793 MMTuple(
794 StructABC,
795 MMTuple(
796 MMString("int"),
797 OmnipotentCharCXX,
798 MConstInt(0)),
799 MConstInt(4))));
800 ASSERT_TRUE(I);
801
802 I = matchNext(I,
803 MInstruction(Instruction::Store,
804 MConstInt(11, 16),
805 MMTuple(
806 StructABC,
807 MMTuple(
808 MMString("short"),
809 OmnipotentCharCXX,
810 MConstInt(0)),
811 MConstInt(0))));
812 ASSERT_TRUE(I);
813
814 I = matchNext(I,
815 MInstruction(Instruction::Store,
816 MConstInt(44, 32),
817 MMTuple(
818 StructCDE,
819 MMTuple(
820 MMString("int"),
821 OmnipotentCharCXX,
822 MConstInt(0)),
823 MConstInt(4))));
824 ASSERT_TRUE(I);
825
826 I = matchNext(I,
827 MInstruction(Instruction::Store,
828 MConstInt(111, 16),
829 MMTuple(
830 StructCDE,
831 MMTuple(
832 MMString("short"),
833 OmnipotentCharCXX,
834 MConstInt(0)),
835 MConstInt(0))));
836 ASSERT_TRUE(I);
837}
838
839TEST(TBAAMetadataTest, StructureFields) {
840 const char TestProgram[] = R"**(
841 struct Inner {
842 int f32;
843 };
844
845 struct Outer {
846 short f16;
847 Inner b1;
848 Inner b2;
849 };
850
851 void func(Outer *S) {
852 S->f16 = 14;
853 S->b1.f32 = 35;
854 S->b2.f32 = 77;
855 }
856 )**";
857
858 TestCompiler Compiler;
859 Compiler.compiler.getLangOpts().CPlusPlus = 1;
860 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
861 Compiler.init(TestProgram);
862 const BasicBlock *BB = Compiler.compile();
863
864 auto StructInner = MMTuple(
865 MMString("_ZTS5Inner"),
866 MMTuple(
867 MMString("int"),
868 OmnipotentCharCXX,
869 MConstInt(0)),
870 MConstInt(0));
871
872 auto StructOuter = MMTuple(
873 MMString("_ZTS5Outer"),
874 MMTuple(
875 MMString("short"),
876 OmnipotentCharCXX,
877 MConstInt(0)),
878 MConstInt(0),
879 StructInner,
880 MConstInt(4),
881 MSameAs(3),
882 MConstInt(8));
883
884 const Instruction *I = match(BB,
885 MInstruction(Instruction::Store,
886 MConstInt(14, 16),
887 MMTuple(
888 StructOuter,
889 MMTuple(
890 MMString("short"),
891 OmnipotentCharCXX,
892 MConstInt(0)),
893 MConstInt(0))));
894 ASSERT_TRUE(I);
895
896 I = matchNext(I,
897 MInstruction(Instruction::Store,
898 MConstInt(35, 32),
899 MMTuple(
900 StructOuter,
901 MMTuple(
902 MMString("int"),
903 OmnipotentCharCXX,
904 MConstInt(0)),
905 MConstInt(4))));
906 ASSERT_TRUE(I);
907
908 I = matchNext(I,
909 MInstruction(Instruction::Store,
910 MConstInt(77, 32),
911 MMTuple(
912 StructOuter,
913 MMTuple(
914 MMString("int"),
915 OmnipotentCharCXX,
916 MConstInt(0)),
917 MConstInt(8))));
918 ASSERT_TRUE(I);
919}
920
921TEST(TBAAMetadataTest, ArrayFields) {
922 const char TestProgram[] = R"**(
923 struct Inner {
924 int f32;
925 };
926
927 struct Outer {
928 short f16;
929 Inner b1[2];
930 };
931
932 void func(Outer *S) {
933 S->f16 = 14;
934 S->b1[0].f32 = 35;
935 S->b1[1].f32 = 77;
936 }
937 )**";
938
939 TestCompiler Compiler;
940 Compiler.compiler.getLangOpts().CPlusPlus = 1;
941 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
942 Compiler.init(TestProgram);
943 const BasicBlock *BB = Compiler.compile();
944
945 auto StructInner = MMTuple(
946 MMString("_ZTS5Inner"),
947 MMTuple(
948 MMString("int"),
949 OmnipotentCharCXX,
950 MConstInt(0)),
951 MConstInt(0));
952
953 auto StructOuter = MMTuple(
954 MMString("_ZTS5Outer"),
955 MMTuple(
956 MMString("short"),
957 OmnipotentCharCXX,
958 MConstInt(0)),
959 MConstInt(0),
960 OmnipotentCharCXX, // FIXME: Info about array field is lost.
961 MConstInt(4));
962
963 const Instruction *I = match(BB,
964 MInstruction(Instruction::Store,
965 MConstInt(14, 16),
966 MMTuple(
967 StructOuter,
968 MMTuple(
969 MMString("short"),
970 OmnipotentCharCXX,
971 MConstInt(0)),
972 MConstInt(0))));
973 ASSERT_TRUE(I);
974
975 I = matchNext(I,
976 MInstruction(Instruction::Store,
977 MConstInt(35, 32),
978 MMTuple(
979 StructInner,
980 MMTuple(
981 MMString("int"),
982 OmnipotentCharCXX,
983 MConstInt(0)),
984 MConstInt(0))));
985 ASSERT_TRUE(I);
986
987 I = matchNext(I,
988 MInstruction(Instruction::Store,
989 MConstInt(77, 32),
990 MMTuple(
991 StructInner,
992 MMTuple(
993 MMString("int"),
994 OmnipotentCharCXX,
995 MConstInt(0)),
996 MConstInt(0))));
997 ASSERT_TRUE(I);
998}
999
1000TEST(TBAAMetadataTest, BaseClass) {
1001 const char TestProgram[] = R"**(
1002 struct Base {
1003 int f32;
1004 };
1005
1006 struct Derived : public Base {
1007 short f16;
1008 };
1009
1010 void func(Base *B, Derived *D) {
1011 B->f32 = 14;
1012 D->f16 = 35;
1013 D->f32 = 77;
1014 }
1015 )**";
1016
1017 TestCompiler Compiler;
1018 Compiler.compiler.getLangOpts().CPlusPlus = 1;
1019 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
1020 Compiler.init(TestProgram);
1021 const BasicBlock *BB = Compiler.compile();
1022
1023 auto ClassBase = MMTuple(
1024 MMString("_ZTS4Base"),
1025 MMTuple(
1026 MMString("int"),
1027 OmnipotentCharCXX,
1028 MConstInt(0)),
1029 MConstInt(0));
1030
1031 auto ClassDerived = MMTuple(
1032 MMString("_ZTS7Derived"),
1033 MMTuple(
1034 MMString("short"),
1035 OmnipotentCharCXX,
1036 MConstInt(0)),
1037 MConstInt(4));
1038
1039 const Instruction *I = match(BB,
1040 MInstruction(Instruction::Store,
1041 MConstInt(14, 32),
1042 MMTuple(
1043 ClassBase,
1044 MMTuple(
1045 MMString("int"),
1046 OmnipotentCharCXX,
1047 MConstInt(0)),
1048 MConstInt(0))));
1049 ASSERT_TRUE(I);
1050
1051 I = matchNext(I,
1052 MInstruction(Instruction::Store,
1053 MConstInt(35, 16),
1054 MMTuple(
1055 ClassDerived,
1056 MMTuple(
1057 MMString("short"),
1058 OmnipotentCharCXX,
1059 MConstInt(0)),
1060 MConstInt(4))));
1061 ASSERT_TRUE(I);
1062
1063 I = matchNext(I,
1064 MInstruction(Instruction::Store,
1065 MConstInt(77, 32),
1066 MMTuple(
1067 ClassBase,
1068 MMTuple(
1069 MMString("int"),
1070 OmnipotentCharCXX,
1071 MConstInt(0)),
1072 MConstInt(0))));
1073 ASSERT_TRUE(I);
1074}
1075
1076TEST(TBAAMetadataTest, PolymorphicClass) {
1077 const char TestProgram[] = R"**(
1078 struct Base {
1079 virtual void m1(int *) = 0;
1080 int f32;
1081 };
1082
1083 struct Derived : public Base {
1084 virtual void m1(int *) override;
1085 short f16;
1086 };
1087
1088 void func(Base *B, Derived *D) {
1089 B->f32 = 14;
1090 D->f16 = 35;
1091 D->f32 = 77;
1092 }
1093 )**";
1094
1095 TestCompiler Compiler;
1096 Compiler.compiler.getLangOpts().CPlusPlus = 1;
1097 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
1098 Compiler.init(TestProgram);
1099 const BasicBlock *BB = Compiler.compile();
1100
1101 auto ClassBase = MMTuple(
1102 MMString("_ZTS4Base"),
1103 MMTuple(
1104 MMString("int"),
1105 OmnipotentCharCXX,
1106 MConstInt(0)),
1107 MConstInt(Compiler.PtrSize));
1108
1109 auto ClassDerived = MMTuple(
1110 MMString("_ZTS7Derived"),
1111 MMTuple(
1112 MMString("short"),
1113 OmnipotentCharCXX,
1114 MConstInt(0)),
1115 MConstInt(Compiler.PtrSize + 4));
1116
1117 const Instruction *I = match(BB,
1118 MInstruction(Instruction::Store,
1119 MConstInt(14, 32),
1120 MMTuple(
1121 ClassBase,
1122 MMTuple(
1123 MMString("int"),
1124 OmnipotentCharCXX,
1125 MConstInt(0)),
1126 MConstInt(Compiler.PtrSize))));
1127 ASSERT_TRUE(I);
1128
1129 I = matchNext(I,
1130 MInstruction(Instruction::Store,
1131 MConstInt(35, 16),
1132 MMTuple(
1133 ClassDerived,
1134 MMTuple(
1135 MMString("short"),
1136 OmnipotentCharCXX,
1137 MConstInt(0)),
1138 MConstInt(Compiler.PtrSize + 4))));
1139 ASSERT_TRUE(I);
1140
1141 I = matchNext(I,
1142 MInstruction(Instruction::Store,
1143 MConstInt(77, 32),
1144 MMTuple(
1145 ClassBase,
1146 MMTuple(
1147 MMString("int"),
1148 OmnipotentCharCXX,
1149 MConstInt(0)),
1150 MConstInt(Compiler.PtrSize))));
1151 ASSERT_TRUE(I);
1152}
1153
1154TEST(TBAAMetadataTest, VirtualBase) {
1155 const char TestProgram[] = R"**(
1156 struct Base {
1157 int f32;
1158 };
1159
1160 struct Derived : public virtual Base {
1161 short f16;
1162 };
1163
1164 void func(Base *B, Derived *D) {
1165 B->f32 = 14;
1166 D->f16 = 35;
1167 D->f32 = 77;
1168 }
1169 )**";
1170
1171 TestCompiler Compiler;
1172 Compiler.compiler.getLangOpts().CPlusPlus = 1;
1173 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
1174 Compiler.init(TestProgram);
1175 const BasicBlock *BB = Compiler.compile();
1176
1177 auto ClassBase = MMTuple(
1178 MMString("_ZTS4Base"),
1179 MMTuple(
1180 MMString("int"),
1181 OmnipotentCharCXX,
1182 MConstInt(0)),
1183 MConstInt(0));
1184
1185 auto ClassDerived = MMTuple(
1186 MMString("_ZTS7Derived"),
1187 MMTuple(
1188 MMString("short"),
1189 OmnipotentCharCXX,
1190 MConstInt(0)),
1191 MConstInt(Compiler.PtrSize));
1192
1193 const Instruction *I = match(BB,
1194 MInstruction(Instruction::Store,
1195 MConstInt(14, 32),
1196 MMTuple(
1197 ClassBase,
1198 MMTuple(
1199 MMString("int"),
1200 OmnipotentCharCXX,
1201 MConstInt(0)),
1202 MConstInt(0))));
1203 ASSERT_TRUE(I);
1204
1205 I = matchNext(I,
1206 MInstruction(Instruction::Store,
1207 MConstInt(35, 16),
1208 MMTuple(
1209 ClassDerived,
1210 MMTuple(
1211 MMString("short"),
1212 OmnipotentCharCXX,
1213 MConstInt(0)),
1214 MConstInt(Compiler.PtrSize))));
1215 ASSERT_TRUE(I);
1216
1217 I = matchNext(I,
1218 MInstruction(Instruction::Load,
1219 MMTuple(
1220 MMTuple(
1221 MMString("vtable pointer"),
1222 MMTuple(
1223 MMString("Simple C++ TBAA")),
1224 MConstInt(0)),
1225 MSameAs(0),
1226 MConstInt(0))));
1227 ASSERT_TRUE(I);
1228
1229 I = matchNext(I,
1230 MInstruction(Instruction::Store,
1231 MConstInt(77, 32),
1232 MMTuple(
1233 ClassBase,
1234 MMTuple(
1235 MMString("int"),
1236 OmnipotentCharCXX,
1237 MConstInt(0)),
1238 MConstInt(0))));
1239 ASSERT_TRUE(I);
1240}
1241
1242TEST(TBAAMetadataTest, TemplSpec) {
1243 const char TestProgram[] = R"**(
1244 template<typename T1, typename T2>
1245 struct ABC {
1246 T1 f1;
1247 T2 f2;
1248 };
1249
1250 void func(ABC<double, int> *p) {
1251 p->f1 = 12.1;
1252 p->f2 = 44;
1253 }
1254 )**";
1255
1256 TestCompiler Compiler;
1257 Compiler.compiler.getLangOpts().CPlusPlus = 1;
1258 Compiler.compiler.getLangOpts().CPlusPlus11 = 1;
1259 Compiler.init(TestProgram);
1260 const BasicBlock *BB = Compiler.compile();
1261
1262 auto SpecABC = MMTuple(
1263 MMString("_ZTS3ABCIdiE"),
1264 MMTuple(
1265 MMString("double"),
1266 OmnipotentCharCXX,
1267 MConstInt(0)),
1268 MConstInt(0),
1269 MMTuple(
1270 MMString("int"),
1271 OmnipotentCharCXX,
1272 MConstInt(0)),
1273 MConstInt(8));
1274
1275 const Instruction *I = match(BB,
1276 MInstruction(Instruction::Store,
1277 MValType(MType([](const Type &T)->bool { return T.isDoubleTy(); })),
1278 MMTuple(
1279 SpecABC,
1280 MMTuple(
1281 MMString("double"),
1282 OmnipotentCharCXX,
1283 MConstInt(0)),
1284 MConstInt(0))));
1285 ASSERT_TRUE(I);
1286
1287 I = matchNext(I,
1288 MInstruction(Instruction::Store,
1289 MConstInt(44, 32),
1290 MMTuple(
1291 SpecABC,
1292 MMTuple(
1293 MMString("int"),
1294 OmnipotentCharCXX,
1295 MConstInt(0)),
1296 MConstInt(8))));
1297 ASSERT_TRUE(I);
1298}
1299}