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