[SCCP] Avoid modifying AdditionalUsers while iterating over it
[llvm-project.git] / clang / unittests / CodeGen / TBAAMetadataTest.cpp
blob149a8e074b692cd7fe07e2dfe58abcd07c2f9b52
1 //=== unittests/CodeGen/TBAAMetadataTest.cpp - Checks metadata generation -===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "IRMatchers.h"
10 #include "TestCompiler.h"
11 #include "clang/AST/ASTConsumer.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/Basic/SourceManager.h"
14 #include "clang/Basic/TargetInfo.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/Support/MemoryBuffer.h"
17 #include "gtest/gtest.h"
18 #include <memory>
20 using namespace llvm;
22 namespace {
24 struct TBAATestCompiler : public TestCompiler {
25 TBAATestCompiler(clang::LangOptions LO, clang::CodeGenOptions CGO)
26 : TestCompiler(LO, CGO) {}
27 static clang::CodeGenOptions getCommonCodeGenOpts() {
28 clang::CodeGenOptions CGOpts;
29 CGOpts.StructPathTBAA = 1;
30 CGOpts.OptimizationLevel = 1;
31 return CGOpts;
35 auto OmnipotentCharC = MMTuple(
36 MMString("omnipotent char"),
37 MMTuple(
38 MMString("Simple C/C++ TBAA")),
39 MConstInt(0, 64)
43 auto OmnipotentCharCXX = MMTuple(
44 MMString("omnipotent char"),
45 MMTuple(
46 MMString("Simple C++ TBAA")),
47 MConstInt(0, 64)
51 TEST(TBAAMetadataTest, BasicTypes) {
52 const char TestProgram[] = R"**(
53 void func(char *CP, short *SP, int *IP, long long *LP, void **VPP,
54 int **IPP) {
55 *CP = 4;
56 *SP = 11;
57 *IP = 601;
58 *LP = 604;
59 *VPP = CP;
60 *IPP = IP;
62 )**";
64 clang::LangOptions LO;
65 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
66 Compiler.init(TestProgram);
67 const BasicBlock *BB = Compiler.compile();
69 const Instruction *I = match(BB,
70 MInstruction(Instruction::Store,
71 MConstInt(4, 8),
72 MMTuple(
73 OmnipotentCharC,
74 MSameAs(0),
75 MConstInt(0))));
76 ASSERT_TRUE(I);
78 I = matchNext(I,
79 MInstruction(Instruction::Store,
80 MConstInt(11, 16),
81 MMTuple(
82 MMTuple(
83 MMString("short"),
84 OmnipotentCharC,
85 MConstInt(0)),
86 MSameAs(0),
87 MConstInt(0))));
88 ASSERT_TRUE(I);
90 I = matchNext(I,
91 MInstruction(Instruction::Store,
92 MConstInt(601, 32),
93 MMTuple(
94 MMTuple(
95 MMString("int"),
96 OmnipotentCharC,
97 MConstInt(0)),
98 MSameAs(0),
99 MConstInt(0))));
100 ASSERT_TRUE(I);
102 I = matchNext(I,
103 MInstruction(Instruction::Store,
104 MConstInt(604, 64),
105 MMTuple(
106 MMTuple(
107 MMString("long long"),
108 OmnipotentCharC,
109 MConstInt(0)),
110 MSameAs(0),
111 MConstInt(0))));
112 ASSERT_TRUE(I);
114 I = matchNext(I,
115 MInstruction(Instruction::Store,
116 MValType(Type::getInt8PtrTy(Compiler.Context)),
117 MMTuple(
118 MMTuple(
119 MMString("any pointer"),
120 OmnipotentCharC,
121 MConstInt(0)),
122 MSameAs(0),
123 MConstInt(0))));
124 ASSERT_TRUE(I);
126 I = matchNext(I,
127 MInstruction(Instruction::Store,
128 MValType(Type::getInt32PtrTy(Compiler.Context)),
129 MMTuple(
130 MMTuple(
131 MMString("any pointer"),
132 OmnipotentCharC,
133 MConstInt(0)),
134 MSameAs(0),
135 MConstInt(0))));
136 ASSERT_TRUE(I);
139 TEST(TBAAMetadataTest, CFields) {
140 const char TestProgram[] = R"**(
141 struct ABC {
142 short f16;
143 int f32;
144 long long f64;
145 unsigned short f16_2;
146 unsigned f32_2;
147 unsigned long long f64_2;
150 void func(struct ABC *A) {
151 A->f32 = 4;
152 A->f16 = 11;
153 A->f64 = 601;
154 A->f16_2 = 22;
155 A->f32_2 = 77;
156 A->f64_2 = 604;
158 )**";
160 clang::LangOptions LO;
161 LO.C11 = 1;
162 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
163 Compiler.init(TestProgram);
164 const BasicBlock *BB = Compiler.compile();
166 auto StructABC = MMTuple(
167 MMString("ABC"),
168 MMTuple(
169 MMString("short"),
170 OmnipotentCharC,
171 MConstInt(0)),
172 MConstInt(0),
173 MMTuple(
174 MMString("int"),
175 OmnipotentCharC,
176 MConstInt(0)),
177 MConstInt(4),
178 MMTuple(
179 MMString("long long"),
180 OmnipotentCharC,
181 MConstInt(0)),
182 MConstInt(8),
183 MSameAs(1),
184 MConstInt(16),
185 MSameAs(3),
186 MConstInt(20),
187 MSameAs(5),
188 MConstInt(24));
190 const Instruction *I = match(BB,
191 MInstruction(Instruction::Store,
192 MConstInt(4, 32),
193 MMTuple(
194 StructABC,
195 MMTuple(
196 MMString("int"),
197 OmnipotentCharC,
198 MConstInt(0)),
199 MConstInt(4))));
200 ASSERT_TRUE(I);
202 I = matchNext(I,
203 MInstruction(Instruction::Store,
204 MConstInt(11, 16),
205 MMTuple(
206 StructABC,
207 MMTuple(
208 MMString("short"),
209 OmnipotentCharC,
210 MConstInt(0)),
211 MConstInt(0))));
212 ASSERT_TRUE(I);
214 I = matchNext(I,
215 MInstruction(Instruction::Store,
216 MConstInt(601, 64),
217 MMTuple(
218 StructABC,
219 MMTuple(
220 MMString("long long"),
221 OmnipotentCharC,
222 MConstInt(0)),
223 MConstInt(8))));
224 ASSERT_TRUE(I);
226 I = matchNext(I,
227 MInstruction(Instruction::Store,
228 MConstInt(22, 16),
229 MMTuple(
230 StructABC,
231 MMTuple(
232 MMString("short"),
233 OmnipotentCharC,
234 MConstInt(0)),
235 MConstInt(16))));
236 ASSERT_TRUE(I);
238 I = matchNext(I,
239 MInstruction(Instruction::Store,
240 MConstInt(77, 32),
241 MMTuple(
242 StructABC,
243 MMTuple(
244 MMString("int"),
245 OmnipotentCharC,
246 MConstInt(0)),
247 MConstInt(20))));
248 ASSERT_TRUE(I);
250 I = matchNext(I,
251 MInstruction(Instruction::Store,
252 MConstInt(604, 64),
253 MMTuple(
254 StructABC,
255 MMTuple(
256 MMString("long long"),
257 OmnipotentCharC,
258 MConstInt(0)),
259 MConstInt(24))));
260 ASSERT_TRUE(I);
263 TEST(TBAAMetadataTest, CTypedefFields) {
264 const char TestProgram[] = R"**(
265 typedef struct {
266 short f16;
267 int f32;
268 } ABC;
269 typedef struct {
270 short value_f16;
271 int value_f32;
272 } CDE;
274 void func(ABC *A, CDE *B) {
275 A->f32 = 4;
276 A->f16 = 11;
277 B->value_f32 = 44;
278 B->value_f16 = 111;
280 )**";
282 clang::LangOptions LO;
283 LO.C11 = 1;
284 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
285 Compiler.init(TestProgram);
286 const BasicBlock *BB = Compiler.compile();
288 auto NamelessStruct = MMTuple(
289 MMString(""),
290 MMTuple(
291 MMString("short"),
292 OmnipotentCharC,
293 MConstInt(0)),
294 MConstInt(0),
295 MMTuple(
296 MMString("int"),
297 OmnipotentCharC,
298 MConstInt(0)),
299 MConstInt(4));
301 const Metadata *MetaABC = nullptr;
302 const Instruction *I = match(BB,
303 MInstruction(Instruction::Store,
304 MConstInt(4, 32),
305 MMTuple(
306 MMSave(MetaABC, NamelessStruct),
307 MMTuple(
308 MMString("int"),
309 OmnipotentCharC,
310 MConstInt(0)),
311 MConstInt(4))));
312 ASSERT_TRUE(I);
314 I = matchNext(I,
315 MInstruction(Instruction::Store,
316 MConstInt(11, 16),
317 MMTuple(
318 NamelessStruct,
319 MMTuple(
320 MMString("short"),
321 OmnipotentCharC,
322 MConstInt(0)),
323 MConstInt(0))));
324 ASSERT_TRUE(I);
326 const Metadata *MetaCDE = nullptr;
327 I = matchNext(I,
328 MInstruction(Instruction::Store,
329 MConstInt(44, 32),
330 MMTuple(
331 MMSave(MetaCDE, NamelessStruct),
332 MMTuple(
333 MMString("int"),
334 OmnipotentCharC,
335 MConstInt(0)),
336 MConstInt(4))));
337 ASSERT_TRUE(I);
339 I = matchNext(I,
340 MInstruction(Instruction::Store,
341 MConstInt(111, 16),
342 MMTuple(
343 NamelessStruct,
344 MMTuple(
345 MMString("short"),
346 OmnipotentCharC,
347 MConstInt(0)),
348 MConstInt(0))));
349 ASSERT_TRUE(I);
351 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are
352 // different structures and must be described by different descriptors.
353 //ASSERT_TRUE(MetaABC != MetaCDE);
356 TEST(TBAAMetadataTest, CTypedefFields2) {
357 const char TestProgram[] = R"**(
358 typedef struct {
359 short f16;
360 int f32;
361 } ABC;
362 typedef struct {
363 short f16;
364 int f32;
365 } CDE;
367 void func(ABC *A, CDE *B) {
368 A->f32 = 4;
369 A->f16 = 11;
370 B->f32 = 44;
371 B->f16 = 111;
373 )**";
375 clang::LangOptions LO;
376 LO.C11 = 1;
377 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
378 Compiler.init(TestProgram);
379 const BasicBlock *BB = Compiler.compile();
381 auto NamelessStruct = MMTuple(
382 MMString(""),
383 MMTuple(
384 MMString("short"),
385 OmnipotentCharC,
386 MConstInt(0)),
387 MConstInt(0),
388 MMTuple(
389 MMString("int"),
390 OmnipotentCharC,
391 MConstInt(0)),
392 MConstInt(4));
394 const Metadata *MetaABC = nullptr;
395 const Instruction *I = match(BB,
396 MInstruction(Instruction::Store,
397 MConstInt(4, 32),
398 MMTuple(
399 MMSave(MetaABC, NamelessStruct),
400 MMTuple(
401 MMString("int"),
402 OmnipotentCharC,
403 MConstInt(0)),
404 MConstInt(4))));
405 ASSERT_TRUE(I);
407 I = matchNext(I,
408 MInstruction(Instruction::Store,
409 MConstInt(11, 16),
410 MMTuple(
411 NamelessStruct,
412 MMTuple(
413 MMString("short"),
414 OmnipotentCharC,
415 MConstInt(0)),
416 MConstInt(0))));
417 ASSERT_TRUE(I);
419 const Metadata *MetaCDE = nullptr;
420 I = matchNext(I,
421 MInstruction(Instruction::Store,
422 MConstInt(44, 32),
423 MMTuple(
424 MMSave(MetaCDE, NamelessStruct),
425 MMTuple(
426 MMString("int"),
427 OmnipotentCharC,
428 MConstInt(0)),
429 MConstInt(4))));
430 ASSERT_TRUE(I);
432 I = matchNext(I,
433 MInstruction(Instruction::Store,
434 MConstInt(111, 16),
435 MMTuple(
436 NamelessStruct,
437 MMTuple(
438 MMString("short"),
439 OmnipotentCharC,
440 MConstInt(0)),
441 MConstInt(0))));
442 ASSERT_TRUE(I);
444 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are
445 // different structures, although they have the same field sequence. They must
446 // be described by different descriptors.
447 //ASSERT_TRUE(MetaABC != MetaCDE);
450 TEST(TBAAMetadataTest, CTypedefFields3) {
451 const char TestProgram[] = R"**(
452 typedef struct {
453 short f16;
454 int f32;
455 } ABC;
456 typedef struct {
457 int f32;
458 short f16;
459 } CDE;
461 void func(ABC *A, CDE *B) {
462 A->f32 = 4;
463 A->f16 = 11;
464 B->f32 = 44;
465 B->f16 = 111;
467 )**";
469 clang::LangOptions LO;
470 LO.C11 = 1;
471 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
472 Compiler.init(TestProgram);
473 const BasicBlock *BB = Compiler.compile();
475 auto NamelessStruct1 = MMTuple(
476 MMString(""),
477 MMTuple(
478 MMString("short"),
479 OmnipotentCharC,
480 MConstInt(0)),
481 MConstInt(0),
482 MMTuple(
483 MMString("int"),
484 OmnipotentCharC,
485 MConstInt(0)),
486 MConstInt(4));
488 auto NamelessStruct2 = MMTuple(
489 MMString(""),
490 MMTuple(
491 MMString("int"),
492 OmnipotentCharC,
493 MConstInt(0)),
494 MConstInt(0),
495 MMTuple(
496 MMString("short"),
497 OmnipotentCharC,
498 MConstInt(0)),
499 MConstInt(4));
501 const Instruction *I = match(BB,
502 MInstruction(Instruction::Store,
503 MConstInt(4, 32),
504 MMTuple(
505 NamelessStruct1,
506 MMTuple(
507 MMString("int"),
508 OmnipotentCharC,
509 MConstInt(0)),
510 MConstInt(4))));
511 ASSERT_TRUE(I);
513 I = matchNext(I,
514 MInstruction(Instruction::Store,
515 MConstInt(11, 16),
516 MMTuple(
517 NamelessStruct1,
518 MMTuple(
519 MMString("short"),
520 OmnipotentCharC,
521 MConstInt(0)),
522 MConstInt(0))));
523 ASSERT_TRUE(I);
525 I = matchNext(I,
526 MInstruction(Instruction::Store,
527 MConstInt(44, 32),
528 MMTuple(
529 NamelessStruct2,
530 MMTuple(
531 MMString("int"),
532 OmnipotentCharC,
533 MConstInt(0)),
534 MConstInt(0))));
535 ASSERT_TRUE(I);
537 I = matchNext(I,
538 MInstruction(Instruction::Store,
539 MConstInt(111, 16),
540 MMTuple(
541 NamelessStruct2,
542 MMTuple(
543 MMString("short"),
544 OmnipotentCharC,
545 MConstInt(0)),
546 MConstInt(4))));
547 ASSERT_TRUE(I);
550 TEST(TBAAMetadataTest, CXXFields) {
551 const char TestProgram[] = R"**(
552 struct ABC {
553 short f16;
554 int f32;
555 long long f64;
556 unsigned short f16_2;
557 unsigned f32_2;
558 unsigned long long f64_2;
561 void func(struct ABC *A) {
562 A->f32 = 4;
563 A->f16 = 11;
564 A->f64 = 601;
565 A->f16_2 = 22;
566 A->f32_2 = 77;
567 A->f64_2 = 604;
569 )**";
571 clang::LangOptions LO;
572 LO.CPlusPlus = 1;
573 LO.CPlusPlus11 = 1;
574 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
575 Compiler.init(TestProgram);
576 const BasicBlock *BB = Compiler.compile();
578 auto StructABC = MMTuple(
579 MMString("_ZTS3ABC"),
580 MMTuple(
581 MMString("short"),
582 OmnipotentCharCXX,
583 MConstInt(0)),
584 MConstInt(0),
585 MMTuple(
586 MMString("int"),
587 OmnipotentCharCXX,
588 MConstInt(0)),
589 MConstInt(4),
590 MMTuple(
591 MMString("long long"),
592 OmnipotentCharCXX,
593 MConstInt(0)),
594 MConstInt(8),
595 MSameAs(1),
596 MConstInt(16),
597 MSameAs(3),
598 MConstInt(20),
599 MSameAs(5),
600 MConstInt(24));
602 const Instruction *I = match(BB,
603 MInstruction(Instruction::Store,
604 MConstInt(4, 32),
605 MMTuple(
606 StructABC,
607 MMTuple(
608 MMString("int"),
609 OmnipotentCharCXX,
610 MConstInt(0)),
611 MConstInt(4))));
612 ASSERT_TRUE(I);
614 I = matchNext(I,
615 MInstruction(Instruction::Store,
616 MConstInt(11, 16),
617 MMTuple(
618 StructABC,
619 MMTuple(
620 MMString("short"),
621 OmnipotentCharCXX,
622 MConstInt(0)),
623 MConstInt(0))));
624 ASSERT_TRUE(I);
626 I = matchNext(I,
627 MInstruction(Instruction::Store,
628 MConstInt(601, 64),
629 MMTuple(
630 StructABC,
631 MMTuple(
632 MMString("long long"),
633 OmnipotentCharCXX,
634 MConstInt(0)),
635 MConstInt(8))));
636 ASSERT_TRUE(I);
638 I = matchNext(I,
639 MInstruction(Instruction::Store,
640 MConstInt(22, 16),
641 MMTuple(
642 StructABC,
643 MMTuple(
644 MMString("short"),
645 OmnipotentCharCXX,
646 MConstInt(0)),
647 MConstInt(16))));
648 ASSERT_TRUE(I);
650 I = matchNext(I,
651 MInstruction(Instruction::Store,
652 MConstInt(77, 32),
653 MMTuple(
654 StructABC,
655 MMTuple(
656 MMString("int"),
657 OmnipotentCharCXX,
658 MConstInt(0)),
659 MConstInt(20))));
660 ASSERT_TRUE(I);
662 I = matchNext(I,
663 MInstruction(Instruction::Store,
664 MConstInt(604, 64),
665 MMTuple(
666 StructABC,
667 MMTuple(
668 MMString("long long"),
669 OmnipotentCharCXX,
670 MConstInt(0)),
671 MConstInt(24))));
672 ASSERT_TRUE(I);
675 TEST(TBAAMetadataTest, CXXTypedefFields) {
676 const char TestProgram[] = R"**(
677 typedef struct {
678 short f16;
679 int f32;
680 } ABC;
681 typedef struct {
682 short value_f16;
683 int value_f32;
684 } CDE;
686 void func(ABC *A, CDE *B) {
687 A->f32 = 4;
688 A->f16 = 11;
689 B->value_f32 = 44;
690 B->value_f16 = 111;
692 )**";
694 clang::LangOptions LO;
695 LO.CPlusPlus = 1;
696 LO.CPlusPlus11 = 1;
697 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
698 Compiler.init(TestProgram);
699 const BasicBlock *BB = Compiler.compile();
701 auto StructABC = MMTuple(
702 MMString("_ZTS3ABC"),
703 MMTuple(
704 MMString("short"),
705 OmnipotentCharCXX,
706 MConstInt(0)),
707 MConstInt(0),
708 MMTuple(
709 MMString("int"),
710 OmnipotentCharCXX,
711 MConstInt(0)),
712 MConstInt(4));
714 auto StructCDE = MMTuple(
715 MMString("_ZTS3CDE"),
716 MMTuple(
717 MMString("short"),
718 OmnipotentCharCXX,
719 MConstInt(0)),
720 MConstInt(0),
721 MMTuple(
722 MMString("int"),
723 OmnipotentCharCXX,
724 MConstInt(0)),
725 MConstInt(4));
727 const Instruction *I = match(BB,
728 MInstruction(Instruction::Store,
729 MConstInt(4, 32),
730 MMTuple(
731 StructABC,
732 MMTuple(
733 MMString("int"),
734 OmnipotentCharCXX,
735 MConstInt(0)),
736 MConstInt(4))));
737 ASSERT_TRUE(I);
739 I = matchNext(I,
740 MInstruction(Instruction::Store,
741 MConstInt(11, 16),
742 MMTuple(
743 StructABC,
744 MMTuple(
745 MMString("short"),
746 OmnipotentCharCXX,
747 MConstInt(0)),
748 MConstInt(0))));
749 ASSERT_TRUE(I);
751 I = matchNext(I,
752 MInstruction(Instruction::Store,
753 MConstInt(44, 32),
754 MMTuple(
755 StructCDE,
756 MMTuple(
757 MMString("int"),
758 OmnipotentCharCXX,
759 MConstInt(0)),
760 MConstInt(4))));
761 ASSERT_TRUE(I);
763 I = matchNext(I,
764 MInstruction(Instruction::Store,
765 MConstInt(111, 16),
766 MMTuple(
767 StructCDE,
768 MMTuple(
769 MMString("short"),
770 OmnipotentCharCXX,
771 MConstInt(0)),
772 MConstInt(0))));
773 ASSERT_TRUE(I);
776 TEST(TBAAMetadataTest, StructureFields) {
777 const char TestProgram[] = R"**(
778 struct Inner {
779 int f32;
782 struct Outer {
783 short f16;
784 Inner b1;
785 Inner b2;
788 void func(Outer *S) {
789 S->f16 = 14;
790 S->b1.f32 = 35;
791 S->b2.f32 = 77;
793 )**";
795 clang::LangOptions LO;
796 LO.CPlusPlus = 1;
797 LO.CPlusPlus11 = 1;
798 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
799 Compiler.init(TestProgram);
800 const BasicBlock *BB = Compiler.compile();
802 auto StructInner = MMTuple(
803 MMString("_ZTS5Inner"),
804 MMTuple(
805 MMString("int"),
806 OmnipotentCharCXX,
807 MConstInt(0)),
808 MConstInt(0));
810 auto StructOuter = MMTuple(
811 MMString("_ZTS5Outer"),
812 MMTuple(
813 MMString("short"),
814 OmnipotentCharCXX,
815 MConstInt(0)),
816 MConstInt(0),
817 StructInner,
818 MConstInt(4),
819 MSameAs(3),
820 MConstInt(8));
822 const Instruction *I = match(BB,
823 MInstruction(Instruction::Store,
824 MConstInt(14, 16),
825 MMTuple(
826 StructOuter,
827 MMTuple(
828 MMString("short"),
829 OmnipotentCharCXX,
830 MConstInt(0)),
831 MConstInt(0))));
832 ASSERT_TRUE(I);
834 I = matchNext(I,
835 MInstruction(Instruction::Store,
836 MConstInt(35, 32),
837 MMTuple(
838 StructOuter,
839 MMTuple(
840 MMString("int"),
841 OmnipotentCharCXX,
842 MConstInt(0)),
843 MConstInt(4))));
844 ASSERT_TRUE(I);
846 I = matchNext(I,
847 MInstruction(Instruction::Store,
848 MConstInt(77, 32),
849 MMTuple(
850 StructOuter,
851 MMTuple(
852 MMString("int"),
853 OmnipotentCharCXX,
854 MConstInt(0)),
855 MConstInt(8))));
856 ASSERT_TRUE(I);
859 TEST(TBAAMetadataTest, ArrayFields) {
860 const char TestProgram[] = R"**(
861 struct Inner {
862 int f32;
865 struct Outer {
866 short f16;
867 Inner b1[2];
870 void func(Outer *S) {
871 S->f16 = 14;
872 S->b1[0].f32 = 35;
873 S->b1[1].f32 = 77;
875 )**";
877 clang::LangOptions LO;
878 LO.CPlusPlus = 1;
879 LO.CPlusPlus11 = 1;
880 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
881 Compiler.init(TestProgram);
882 const BasicBlock *BB = Compiler.compile();
884 auto StructInner = MMTuple(
885 MMString("_ZTS5Inner"),
886 MMTuple(
887 MMString("int"),
888 OmnipotentCharCXX,
889 MConstInt(0)),
890 MConstInt(0));
892 auto StructOuter = MMTuple(
893 MMString("_ZTS5Outer"),
894 MMTuple(
895 MMString("short"),
896 OmnipotentCharCXX,
897 MConstInt(0)),
898 MConstInt(0),
899 OmnipotentCharCXX, // FIXME: Info about array field is lost.
900 MConstInt(4));
902 const Instruction *I = match(BB,
903 MInstruction(Instruction::Store,
904 MConstInt(14, 16),
905 MMTuple(
906 StructOuter,
907 MMTuple(
908 MMString("short"),
909 OmnipotentCharCXX,
910 MConstInt(0)),
911 MConstInt(0))));
912 ASSERT_TRUE(I);
914 I = matchNext(I,
915 MInstruction(Instruction::Store,
916 MConstInt(35, 32),
917 MMTuple(
918 StructInner,
919 MMTuple(
920 MMString("int"),
921 OmnipotentCharCXX,
922 MConstInt(0)),
923 MConstInt(0))));
924 ASSERT_TRUE(I);
926 I = matchNext(I,
927 MInstruction(Instruction::Store,
928 MConstInt(77, 32),
929 MMTuple(
930 StructInner,
931 MMTuple(
932 MMString("int"),
933 OmnipotentCharCXX,
934 MConstInt(0)),
935 MConstInt(0))));
936 ASSERT_TRUE(I);
939 TEST(TBAAMetadataTest, BaseClass) {
940 const char TestProgram[] = R"**(
941 struct Base {
942 int f32;
945 struct Derived : public Base {
946 short f16;
949 void func(Base *B, Derived *D) {
950 B->f32 = 14;
951 D->f16 = 35;
952 D->f32 = 77;
954 )**";
956 clang::LangOptions LO;
957 LO.CPlusPlus = 1;
958 LO.CPlusPlus11 = 1;
959 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
960 Compiler.init(TestProgram);
961 const BasicBlock *BB = Compiler.compile();
963 auto ClassBase = MMTuple(
964 MMString("_ZTS4Base"),
965 MMTuple(
966 MMString("int"),
967 OmnipotentCharCXX,
968 MConstInt(0)),
969 MConstInt(0));
971 auto ClassDerived = MMTuple(
972 MMString("_ZTS7Derived"),
973 MMTuple(
974 MMString("short"),
975 OmnipotentCharCXX,
976 MConstInt(0)),
977 MConstInt(4));
979 const Instruction *I = match(BB,
980 MInstruction(Instruction::Store,
981 MConstInt(14, 32),
982 MMTuple(
983 ClassBase,
984 MMTuple(
985 MMString("int"),
986 OmnipotentCharCXX,
987 MConstInt(0)),
988 MConstInt(0))));
989 ASSERT_TRUE(I);
991 I = matchNext(I,
992 MInstruction(Instruction::Store,
993 MConstInt(35, 16),
994 MMTuple(
995 ClassDerived,
996 MMTuple(
997 MMString("short"),
998 OmnipotentCharCXX,
999 MConstInt(0)),
1000 MConstInt(4))));
1001 ASSERT_TRUE(I);
1003 I = matchNext(I,
1004 MInstruction(Instruction::Store,
1005 MConstInt(77, 32),
1006 MMTuple(
1007 ClassBase,
1008 MMTuple(
1009 MMString("int"),
1010 OmnipotentCharCXX,
1011 MConstInt(0)),
1012 MConstInt(0))));
1013 ASSERT_TRUE(I);
1016 TEST(TBAAMetadataTest, PolymorphicClass) {
1017 const char TestProgram[] = R"**(
1018 struct Base {
1019 virtual void m1(int *) = 0;
1020 int f32;
1023 struct Derived : public Base {
1024 virtual void m1(int *) override;
1025 short f16;
1028 void func(Base *B, Derived *D) {
1029 B->f32 = 14;
1030 D->f16 = 35;
1031 D->f32 = 77;
1033 )**";
1035 clang::LangOptions LO;
1036 LO.CPlusPlus = 1;
1037 LO.CPlusPlus11 = 1;
1038 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1039 Compiler.init(TestProgram);
1040 const BasicBlock *BB = Compiler.compile();
1042 auto ClassBase = MMTuple(
1043 MMString("_ZTS4Base"),
1044 MMTuple(
1045 MMString("int"),
1046 OmnipotentCharCXX,
1047 MConstInt(0)),
1048 MConstInt(Compiler.PtrSize));
1050 auto ClassDerived = MMTuple(
1051 MMString("_ZTS7Derived"),
1052 MMTuple(
1053 MMString("short"),
1054 OmnipotentCharCXX,
1055 MConstInt(0)),
1056 MConstInt(Compiler.PtrSize + 4));
1058 const Instruction *I = match(BB,
1059 MInstruction(Instruction::Store,
1060 MConstInt(14, 32),
1061 MMTuple(
1062 ClassBase,
1063 MMTuple(
1064 MMString("int"),
1065 OmnipotentCharCXX,
1066 MConstInt(0)),
1067 MConstInt(Compiler.PtrSize))));
1068 ASSERT_TRUE(I);
1070 I = matchNext(I,
1071 MInstruction(Instruction::Store,
1072 MConstInt(35, 16),
1073 MMTuple(
1074 ClassDerived,
1075 MMTuple(
1076 MMString("short"),
1077 OmnipotentCharCXX,
1078 MConstInt(0)),
1079 MConstInt(Compiler.PtrSize + 4))));
1080 ASSERT_TRUE(I);
1082 I = matchNext(I,
1083 MInstruction(Instruction::Store,
1084 MConstInt(77, 32),
1085 MMTuple(
1086 ClassBase,
1087 MMTuple(
1088 MMString("int"),
1089 OmnipotentCharCXX,
1090 MConstInt(0)),
1091 MConstInt(Compiler.PtrSize))));
1092 ASSERT_TRUE(I);
1095 TEST(TBAAMetadataTest, VirtualBase) {
1096 const char TestProgram[] = R"**(
1097 struct Base {
1098 int f32;
1101 struct Derived : public virtual Base {
1102 short f16;
1105 void func(Base *B, Derived *D) {
1106 B->f32 = 14;
1107 D->f16 = 35;
1108 D->f32 = 77;
1110 )**";
1112 clang::LangOptions LO;
1113 LO.CPlusPlus = 1;
1114 LO.CPlusPlus11 = 1;
1115 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1116 Compiler.init(TestProgram);
1117 const BasicBlock *BB = Compiler.compile();
1119 auto ClassBase = MMTuple(
1120 MMString("_ZTS4Base"),
1121 MMTuple(
1122 MMString("int"),
1123 OmnipotentCharCXX,
1124 MConstInt(0)),
1125 MConstInt(0));
1127 auto ClassDerived = MMTuple(
1128 MMString("_ZTS7Derived"),
1129 MMTuple(
1130 MMString("short"),
1131 OmnipotentCharCXX,
1132 MConstInt(0)),
1133 MConstInt(Compiler.PtrSize));
1135 const Instruction *I = match(BB,
1136 MInstruction(Instruction::Store,
1137 MConstInt(14, 32),
1138 MMTuple(
1139 ClassBase,
1140 MMTuple(
1141 MMString("int"),
1142 OmnipotentCharCXX,
1143 MConstInt(0)),
1144 MConstInt(0))));
1145 ASSERT_TRUE(I);
1147 I = matchNext(I,
1148 MInstruction(Instruction::Store,
1149 MConstInt(35, 16),
1150 MMTuple(
1151 ClassDerived,
1152 MMTuple(
1153 MMString("short"),
1154 OmnipotentCharCXX,
1155 MConstInt(0)),
1156 MConstInt(Compiler.PtrSize))));
1157 ASSERT_TRUE(I);
1159 I = matchNext(I,
1160 MInstruction(Instruction::Load,
1161 MMTuple(
1162 MMTuple(
1163 MMString("vtable pointer"),
1164 MMTuple(
1165 MMString("Simple C++ TBAA")),
1166 MConstInt(0)),
1167 MSameAs(0),
1168 MConstInt(0))));
1169 ASSERT_TRUE(I);
1171 I = matchNext(I,
1172 MInstruction(Instruction::Store,
1173 MConstInt(77, 32),
1174 MMTuple(
1175 ClassBase,
1176 MMTuple(
1177 MMString("int"),
1178 OmnipotentCharCXX,
1179 MConstInt(0)),
1180 MConstInt(0))));
1181 ASSERT_TRUE(I);
1184 TEST(TBAAMetadataTest, TemplSpec) {
1185 const char TestProgram[] = R"**(
1186 template<typename T1, typename T2>
1187 struct ABC {
1188 T1 f1;
1189 T2 f2;
1192 void func(ABC<double, int> *p) {
1193 p->f1 = 12.1;
1194 p->f2 = 44;
1196 )**";
1198 clang::LangOptions LO;
1199 LO.CPlusPlus = 1;
1200 LO.CPlusPlus11 = 1;
1201 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1202 Compiler.init(TestProgram);
1203 const BasicBlock *BB = Compiler.compile();
1205 auto SpecABC = MMTuple(
1206 MMString("_ZTS3ABCIdiE"),
1207 MMTuple(
1208 MMString("double"),
1209 OmnipotentCharCXX,
1210 MConstInt(0)),
1211 MConstInt(0),
1212 MMTuple(
1213 MMString("int"),
1214 OmnipotentCharCXX,
1215 MConstInt(0)),
1216 MConstInt(8));
1218 const Instruction *I = match(BB,
1219 MInstruction(Instruction::Store,
1220 MValType(MType([](const Type &T)->bool { return T.isDoubleTy(); })),
1221 MMTuple(
1222 SpecABC,
1223 MMTuple(
1224 MMString("double"),
1225 OmnipotentCharCXX,
1226 MConstInt(0)),
1227 MConstInt(0))));
1228 ASSERT_TRUE(I);
1230 I = matchNext(I,
1231 MInstruction(Instruction::Store,
1232 MConstInt(44, 32),
1233 MMTuple(
1234 SpecABC,
1235 MMTuple(
1236 MMString("int"),
1237 OmnipotentCharCXX,
1238 MConstInt(0)),
1239 MConstInt(8))));
1240 ASSERT_TRUE(I);