Skip to content

Commit a01672a

Browse files
committed
[TBAA] Emit distinct TBAA tags for pointers with different depths,types.
This patch extends Clang's TBAA generation code to emit distinct tags for incompatible pointer types. Pointers with different element types are incompatible if the pointee types are also incompatible (modulo sugar/modifiers). Express this in TBAA by generating different tags for pointers based on the pointer depth and pointee type. To get the TBAA tag for the pointee type it uses getTypeInfoHelper on the pointee type. (Moved from https://reviews.llvm.org/D122573)
1 parent 581fd2f commit a01672a

File tree

11 files changed

+712
-591
lines changed

11 files changed

+712
-591
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Defa
231231

232232
CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
233233
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
234+
CODEGENOPT(RelaxedPointerAliasing , 1, 0) ///< Set when -fno-pointer-tbaa is enabled.
234235
CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA.
235236
CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-path TBAA.
236237
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3378,6 +3378,7 @@ def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
33783378
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
33793379
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
33803380
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
3381+
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
33813382
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
33823383
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
33833384
"Directly create compilation output files. This may lead to incorrect incremental builds if the compiler crashes">,
@@ -3877,6 +3878,7 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
38773878
" overwriting polymorphic C++ objects">,
38783879
NegFlag<SetFalse>>;
38793880
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
3881+
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
38803882
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
38813883
Visibility<[ClangOption, CLOption, DXCOption]>,
38823884
Group<Action_Group>, HelpText<"Only run the driver.">;
@@ -7112,6 +7114,9 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie
71127114
def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
71137115
HelpText<"Turn off Type Based Alias Analysis">,
71147116
MarshallingInfoFlag<CodeGenOpts<"RelaxedAliasing">>;
7117+
def relaxed_pointer_aliasing : Flag<["-"], "relaxed-pointer-aliasing">,
7118+
HelpText<"Turn off Type Based Alias Analysis for pointer accesses">,
7119+
MarshallingInfoFlag<CodeGenOpts<"RelaxedPointerAliasing">>;
71157120
def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">,
71167121
HelpText<"Turn off struct-path aware Type Based Alias Analysis">,
71177122
MarshallingInfoNegativeFlag<CodeGenOpts<"StructPathTBAA">>;

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,33 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
185185
return getChar();
186186

187187
// Handle pointers and references.
188-
// TODO: Implement C++'s type "similarity" and consider dis-"similar"
189-
// pointers distinct.
190-
if (Ty->isPointerType() || Ty->isReferenceType())
191-
return createScalarTypeNode("any pointer", getChar(), Size);
188+
if (Ty->isPointerType() || Ty->isReferenceType()) {
189+
llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size);
190+
if (CodeGenOpts.RelaxedPointerAliasing)
191+
return AnyPtr;
192+
// Compute the depth of the pointer and generate a tag of the form "p<depth>
193+
// <base type tag>".
194+
unsigned PtrDepth = 0;
195+
do {
196+
PtrDepth++;
197+
Ty = Ty->getPointeeType().getTypePtr();
198+
} while (Ty->isPointerType() || Ty->isReferenceType());
199+
// TODO: Implement C++'s type "similarity" and consider dis-"similar"
200+
// pointers distinct for non-builtin types.
201+
if (isa<BuiltinType>(Ty)) {
202+
llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
203+
StringRef Name =
204+
cast<llvm::MDString>(
205+
ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
206+
->getString();
207+
SmallString<256> OutName("p");
208+
OutName += std::to_string(PtrDepth);
209+
OutName += " ";
210+
OutName += Name;
211+
return createScalarTypeNode(OutName, AnyPtr, Size);
212+
}
213+
return AnyPtr;
214+
}
192215

193216
// Accesses to arrays are accesses to objects of their element types.
194217
if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,6 +5707,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
57075707
if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
57085708
options::OPT_fno_strict_aliasing, !IsWindowsMSVC))
57095709
CmdArgs.push_back("-relaxed-aliasing");
5710+
if (!Args.hasFlag(options::OPT_fpointer_tbaa, options::OPT_fno_pointer_tbaa,
5711+
true))
5712+
CmdArgs.push_back("-relaxed-pointer-aliasing");
57105713
if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
57115714
options::OPT_fno_struct_path_tbaa, true))
57125715
CmdArgs.push_back("-no-struct-path-tbaa");

clang/test/CXX/drs/cwg158.cpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,68 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
12
// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
23
// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
34
// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
45
// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
56

67
// cwg158: yes
78

8-
// CHECK-LABEL: define {{.*}} @_Z1f
9+
// CHECK-LABEL: define dso_local noundef ptr @_Z1fPKPKiPPi(
10+
// CHECK-SAME: ptr noundef [[P:%.*]], ptr noundef [[Q:%.*]]) #[[ATTR0:[0-9]+]] {
11+
// CHECK-NEXT: [[ENTRY:.*:]]
12+
// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8
13+
// CHECK-NEXT: [[Q_ADDR:%.*]] = alloca ptr, align 8
14+
// CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8
15+
// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8, !tbaa [[TBAA2:![0-9]+]]
16+
// CHECK-NEXT: store ptr [[Q]], ptr [[Q_ADDR]], align 8, !tbaa [[TBAA2]]
17+
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]]) #[[ATTR2:[0-9]+]]
18+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8, !tbaa [[TBAA2]]
19+
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA7:![0-9]+]]
20+
// CHECK-NEXT: store ptr [[TMP1]], ptr [[X]], align 8, !tbaa [[TBAA7]]
21+
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[Q_ADDR]], align 8, !tbaa [[TBAA2]]
22+
// CHECK-NEXT: store ptr null, ptr [[TMP2]], align 8, !tbaa [[TBAA7]]
23+
// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[X]], align 8, !tbaa [[TBAA7]]
24+
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]]) #[[ATTR2]]
25+
// CHECK-NEXT: ret ptr [[TMP3]]
26+
//
927
const int *f(const int * const *p, int **q) {
10-
// CHECK: load ptr, {{.*}}, !tbaa ![[INTPTR_TBAA:[^,]*]]
1128
const int *x = *p;
12-
// CHECK: store ptr null, {{.*}}, !tbaa ![[INTPTR_TBAA]]
1329
*q = 0;
1430
return x;
1531
}
1632

1733
struct A {};
1834

19-
// CHECK-LABEL: define {{.*}} @_Z1g
35+
// CHECK-LABEL: define dso_local noundef ptr @_Z1gPPKM1AA3_PKiPPMS_A3_Pi(
36+
// CHECK-SAME: ptr noundef [[P:%.*]], ptr noundef [[Q:%.*]]) #[[ATTR0]] {
37+
// CHECK-NEXT: [[ENTRY:.*:]]
38+
// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8
39+
// CHECK-NEXT: [[Q_ADDR:%.*]] = alloca ptr, align 8
40+
// CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8
41+
// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8, !tbaa [[TBAA9:![0-9]+]]
42+
// CHECK-NEXT: store ptr [[Q]], ptr [[Q_ADDR]], align 8, !tbaa [[TBAA9]]
43+
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]]) #[[ATTR2]]
44+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8, !tbaa [[TBAA9]]
45+
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]]
46+
// CHECK-NEXT: store ptr [[TMP1]], ptr [[X]], align 8, !tbaa [[TBAA9]]
47+
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[Q_ADDR]], align 8, !tbaa [[TBAA9]]
48+
// CHECK-NEXT: store ptr null, ptr [[TMP2]], align 8, !tbaa [[TBAA9]]
49+
// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[X]], align 8, !tbaa [[TBAA9]]
50+
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]]) #[[ATTR2]]
51+
// CHECK-NEXT: ret ptr [[TMP3]]
52+
//
2053
const int *(A::*const *g(const int *(A::* const **p)[3], int *(A::***q)[3]))[3] {
21-
// CHECK: load ptr, {{.*}}, !tbaa ![[MEMPTR_TBAA:[^,]*]]
2254
const int *(A::*const *x)[3] = *p;
23-
// CHECK: store ptr null, {{.*}}, !tbaa ![[MEMPTR_TBAA]]
2455
*q = 0;
2556
return x;
2657
}
2758

59+
//.
60+
// CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
61+
// CHECK: [[META3]] = !{!"p2 int", [[META4:![0-9]+]], i64 0}
62+
// CHECK: [[META4]] = !{!"any pointer", [[META5:![0-9]+]], i64 0}
63+
// CHECK: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0}
64+
// CHECK: [[META6]] = !{!"Simple C++ TBAA"}
65+
// CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
66+
// CHECK: [[META8]] = !{!"p1 int", [[META4]], i64 0}
67+
// CHECK: [[TBAA9]] = !{[[META4]], [[META4]], i64 0}
68+
//.

clang/test/CodeGen/sanitize-metadata-nosanitize.c

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//.
1313
// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
1414
// CHECK-LABEL: define dso_local void @escape
15-
// CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections !2 {
15+
// CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] {
1616
// CHECK-NEXT: entry:
1717
// CHECK-NEXT: ret void
1818
//
@@ -23,13 +23,13 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) {
2323

2424
// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
2525
// CHECK-LABEL: define dso_local i32 @normal_function
26-
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections !4 {
26+
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] {
2727
// CHECK-NEXT: entry:
2828
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
2929
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6:![0-9]+]]
30-
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10
30+
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11:![0-9]+]]
3131
// CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]])
32-
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11:![0-9]+]]
32+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12:![0-9]+]]
3333
// CHECK-NEXT: ret i32 [[TMP0]]
3434
//
3535
int normal_function(int *x, int *y) {
@@ -46,7 +46,7 @@ int normal_function(int *x, int *y) {
4646
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]]
4747
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4
4848
// CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]])
49-
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]]
49+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]]
5050
// CHECK-NEXT: ret i32 [[TMP0]]
5151
//
5252
__attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_instrumentation(int *x, int *y) {
@@ -57,13 +57,13 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins
5757

5858
// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
5959
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread
60-
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections !13 {
60+
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] {
6161
// CHECK-NEXT: entry:
6262
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
6363
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]]
64-
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10
64+
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11]]
6565
// CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]])
66-
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]]
66+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]]
6767
// CHECK-NEXT: ret i32 [[TMP0]]
6868
//
6969
__attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int *y) {
@@ -74,13 +74,13 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int *
7474

7575
// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
7676
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_all
77-
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections !13 {
77+
// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] {
7878
// CHECK-NEXT: entry:
7979
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
8080
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]]
81-
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections !10
81+
// CHECK-NEXT: store atomic i32 1, ptr [[X]] monotonic, align 4, !pcsections [[META11]]
8282
// CHECK-NEXT: notail call void @escape(ptr noundef nonnull [[X_ADDR]])
83-
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA11]]
83+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA12]]
8484
// CHECK-NEXT: ret i32 [[TMP0]]
8585
//
8686
__attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) {
@@ -89,23 +89,26 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) {
8989
return *y;
9090
}
9191
//.
92-
// CHECK: attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
93-
// CHECK: attributes #1 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
94-
// CHECK: attributes #2 = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
95-
// CHECK: attributes #3 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
96-
// CHECK: attributes #4 = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
92+
// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
93+
// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
94+
// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
95+
// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
96+
// CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
9797
//.
98-
// CHECK: !2 = !{!"sanmd_covered!C", !3}
99-
// CHECK: !3 = !{i64 0}
100-
// CHECK: !4 = !{!"sanmd_covered!C", !5}
101-
// CHECK: !5 = !{i64 3}
102-
// CHECK: !6 = !{!7, !7, i64 0}
103-
// CHECK: !7 = !{!"any pointer", !8, i64 0}
104-
// CHECK: !8 = !{!"omnipotent char", !9, i64 0}
105-
// CHECK: !9 = !{!"Simple C/C++ TBAA"}
106-
// CHECK: !10 = !{!"sanmd_atomics!C"}
107-
// CHECK: !11 = !{!12, !12, i64 0}
108-
// CHECK: !12 = !{!"int", !8, i64 0}
109-
// CHECK: !13 = !{!"sanmd_covered!C", !14}
110-
// CHECK: !14 = !{i64 2}
98+
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
99+
// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
100+
// CHECK: [[META2]] = !{!"sanmd_covered!C", [[META3:![0-9]+]]}
101+
// CHECK: [[META3]] = !{i64 0}
102+
// CHECK: [[META4]] = !{!"sanmd_covered!C", [[META5:![0-9]+]]}
103+
// CHECK: [[META5]] = !{i64 3}
104+
// CHECK: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
105+
// CHECK: [[META7]] = !{!"p1 int", [[META8:![0-9]+]], i64 0}
106+
// CHECK: [[META8]] = !{!"any pointer", [[META9:![0-9]+]], i64 0}
107+
// CHECK: [[META9]] = !{!"omnipotent char", [[META10:![0-9]+]], i64 0}
108+
// CHECK: [[META10]] = !{!"Simple C/C++ TBAA"}
109+
// CHECK: [[META11]] = !{!"sanmd_atomics!C"}
110+
// CHECK: [[TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
111+
// CHECK: [[META13]] = !{!"int", [[META9]], i64 0}
112+
// CHECK: [[META14]] = !{!"sanmd_covered!C", [[META15:![0-9]+]]}
113+
// CHECK: [[META15]] = !{i64 2}
111114
//.

0 commit comments

Comments
 (0)