xref: /llvm-project/llvm/test/Transforms/LoopIdiom/memset-tbaa.ll (revision 055fb7795aa219a3d274d280ec9129784f169f56)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes="loop-idiom" < %s -S | FileCheck %s
3
4
5define dso_local void @double_memset(ptr nocapture %p) {
6; CHECK-LABEL: @double_memset(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 0, i64 16, i1 false), !tbaa [[TBAA0:![0-9]+]]
9; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
10; CHECK:       for.cond.cleanup:
11; CHECK-NEXT:    ret void
12; CHECK:       for.body:
13; CHECK-NEXT:    [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
14; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[I_07]]
15; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_07]], 1
16; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 16
17; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
18;
19entry:
20  br label %for.body
21
22for.cond.cleanup:
23  ret void
24
25for.body:
26  %i.07 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
27  %ptr1 = getelementptr inbounds i8, ptr %p, i64 %i.07
28  store i8 0, ptr %ptr1, align 1, !tbaa !5
29  %inc = add nuw nsw i64 %i.07, 1
30  %exitcond.not = icmp eq i64 %inc, 16
31  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
32}
33
34
35define dso_local void @struct_memset(ptr nocapture %p) {
36; CHECK-LABEL: @struct_memset(
37; CHECK-NEXT:  entry:
38; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 0, i64 16, i1 false), !tbaa [[TBAA4:![0-9]+]]
39; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
40; CHECK:       for.cond.cleanup:
41; CHECK-NEXT:    ret void
42; CHECK:       for.body:
43; CHECK-NEXT:    [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
44; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[I_07]]
45; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_07]], 1
46; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 16
47; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
48;
49entry:
50  br label %for.body
51
52for.cond.cleanup:
53  ret void
54
55for.body:
56  %i.07 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
57  %ptr1 = getelementptr inbounds i8, ptr %p, i64 %i.07
58  store i8 0, ptr %ptr1, align 1, !tbaa !10
59  %inc = add nuw nsw i64 %i.07, 1
60  %exitcond.not = icmp eq i64 %inc, 16
61  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
62}
63
64define dso_local void @var_memset(ptr nocapture %p, i64 %len) {
65; CHECK-LABEL: @var_memset(
66; CHECK-NEXT:  entry:
67; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
68; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
69; CHECK:       for.cond.cleanup:
70; CHECK-NEXT:    ret void
71; CHECK:       for.body:
72; CHECK-NEXT:    [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
73; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[I_07]]
74; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_07]], 1
75; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[LEN]]
76; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
77;
78entry:
79  br label %for.body
80
81for.cond.cleanup:
82  ret void
83
84for.body:
85  %i.07 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
86  %ptr1 = getelementptr inbounds i8, ptr %p, i64 %i.07
87  store i8 0, ptr %ptr1, align 1, !tbaa !10
88  %inc = add nuw nsw i64 %i.07, 1
89  %exitcond.not = icmp eq i64 %inc, %len
90  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
91}
92
93%struct.A = type { ptr, %struct.B }
94%struct.B = type { ptr }
95
96define dso_local void @adjacent_store_memset(ptr nocapture %a, i64 %len) {
97; CHECK-LABEL: @adjacent_store_memset(
98; CHECK-NEXT:  entry:
99; CHECK-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[LEN:%.*]], i64 1)
100; CHECK-NEXT:    [[TMP0:%.*]] = shl nuw i64 [[UMAX]], 4
101; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[A:%.*]], i8 0, i64 [[TMP0]], i1 false), !tbaa [[TBAA8:![0-9]+]]
102; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
103; CHECK:       for.cond.cleanup:
104; CHECK-NEXT:    ret void
105; CHECK:       for.body:
106; CHECK-NEXT:    [[I_09:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
107; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[A]], i64 [[I_09]], i32 0
108; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i64 [[I_09]], i32 1, i32 0
109; CHECK-NEXT:    [[INC]] = add i64 [[I_09]], 1
110; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], [[LEN]]
111; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
112;
113entry:
114  br label %for.body
115
116for.cond.cleanup:
117  ret void
118
119for.body:
120  %i.09 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
121  %p = getelementptr inbounds %struct.A, ptr %a, i64 %i.09, i32 0
122  store ptr null, ptr %p, align 8, !tbaa !18
123  %p2 = getelementptr inbounds %struct.A, ptr %a, i64 %i.09, i32 1, i32 0
124  store ptr null, ptr %p2, align 8, !tbaa !21
125  %inc = add i64 %i.09, 1
126  %cmp = icmp ult i64 %inc, %len
127  br i1 %cmp, label %for.body, label %for.cond.cleanup
128}
129
130
131
132
133!5 = !{!6, !6, i64 0}
134!6 = !{!"double", !7, i64 0}
135!7 = !{!"omnipotent char", !8, i64 0}
136!8 = !{!"Simple C++ TBAA"}
137
138!15 = !{!8, i64 0, !"omnipotent char"}
139!17 = !{!15, i64 8, !"double"}
140!9 = !{!15, i64 32, !"_ZTS1A", !17, i64 0, i64 8, !17, i64 8, i64 8, !17, i64 16, i64 8, !17, i64 24, i64 8}
141!10 = !{!9, !17, i64 0, i64 1}
142
143!18 = !{!19, !20, i64 0}
144!19 = !{!"A", !20, i64 0, !22, i64 8}
145!20 = !{!"any pointer", !7, i64 0}
146!21 = !{!22, !20, i64 0}
147!22 = !{!"B", !20, i64 0}
148