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