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