• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
3; RUN: opt < %s -alignment-from-assumptions -S | FileCheck %s
4; RUN: opt < %s -passes=alignment-from-assumptions -S | FileCheck %s
5
6define i32 @foo(i32* nocapture %a) nounwind uwtable readonly {
7; CHECK-LABEL: define {{[^@]+}}@foo
8; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
11; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[A]], align 32
12; CHECK-NEXT:    ret i32 [[TMP0]]
13;
14entry:
15  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
16  %0 = load i32, i32* %a, align 4
17  ret i32 %0
18
19}
20
21define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly {
22; CHECK-LABEL: define {{[^@]+}}@foo2
23; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
24; CHECK-NEXT:  entry:
25; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 24) ]
26; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 2
27; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16
28; CHECK-NEXT:    ret i32 [[TMP0]]
29;
30entry:
31  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 24)]
32  %arrayidx = getelementptr inbounds i32, i32* %a, i64 2
33  %0 = load i32, i32* %arrayidx, align 4
34  ret i32 %0
35
36}
37
38define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly {
39; CHECK-LABEL: define {{[^@]+}}@foo2a
40; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 28) ]
43; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -1
44; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32
45; CHECK-NEXT:    ret i32 [[TMP0]]
46;
47entry:
48  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 28)]
49  %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1
50  %0 = load i32, i32* %arrayidx, align 4
51  ret i32 %0
52
53}
54
55define i32 @goo(i32* nocapture %a) nounwind uwtable readonly {
56; CHECK-LABEL: define {{[^@]+}}@goo
57; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
58; CHECK-NEXT:  entry:
59; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
60; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[A]], align 32
61; CHECK-NEXT:    ret i32 [[TMP0]]
62;
63entry:
64  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
65  %0 = load i32, i32* %a, align 4
66  ret i32 %0
67
68}
69
70define i32 @hoo(i32* nocapture %a) nounwind uwtable readonly {
71; CHECK-LABEL: define {{[^@]+}}@hoo
72; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
73; CHECK-NEXT:  entry:
74; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
75; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
76; CHECK:       for.body:
77; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
78; CHECK-NEXT:    [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
79; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
80; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32
81; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[R_06]]
82; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8
83; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
84; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048
85; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
86; CHECK:       for.end:
87; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
88; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
89;
90entry:
91  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
92  br label %for.body
93
94for.body:                                         ; preds = %entry, %for.body
95  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
96  %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
97  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
98  %0 = load i32, i32* %arrayidx, align 4
99  %add = add nsw i32 %0, %r.06
100  %indvars.iv.next = add i64 %indvars.iv, 8
101  %1 = trunc i64 %indvars.iv.next to i32
102  %cmp = icmp slt i32 %1, 2048
103  br i1 %cmp, label %for.body, label %for.end
104
105for.end:                                          ; preds = %for.body
106  %add.lcssa = phi i32 [ %add, %for.body ]
107  ret i32 %add.lcssa
108
109}
110
111define i32 @joo(i32* nocapture %a) nounwind uwtable readonly {
112; CHECK-LABEL: define {{[^@]+}}@joo
113; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
114; CHECK-NEXT:  entry:
115; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
116; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
117; CHECK:       for.body:
118; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
119; CHECK-NEXT:    [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
120; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
121; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16
122; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[R_06]]
123; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8
124; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
125; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048
126; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
127; CHECK:       for.end:
128; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
129; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
130;
131entry:
132  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
133  br label %for.body
134
135for.body:                                         ; preds = %entry, %for.body
136  %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ]
137  %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
138  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
139  %0 = load i32, i32* %arrayidx, align 4
140  %add = add nsw i32 %0, %r.06
141  %indvars.iv.next = add i64 %indvars.iv, 8
142  %1 = trunc i64 %indvars.iv.next to i32
143  %cmp = icmp slt i32 %1, 2048
144  br i1 %cmp, label %for.body, label %for.end
145
146for.end:                                          ; preds = %for.body
147  %add.lcssa = phi i32 [ %add, %for.body ]
148  ret i32 %add.lcssa
149
150}
151
152define i32 @koo(i32* nocapture %a) nounwind uwtable readonly {
153; CHECK-LABEL: define {{[^@]+}}@koo
154; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
155; CHECK-NEXT:  entry:
156; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
157; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
158; CHECK:       for.body:
159; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
160; CHECK-NEXT:    [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
161; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
162; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16
163; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[R_06]]
164; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4
165; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
166; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048
167; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
168; CHECK:       for.end:
169; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
170; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
171;
172entry:
173  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
174  br label %for.body
175
176for.body:                                         ; preds = %entry, %for.body
177  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
178  %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
179  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
180  %0 = load i32, i32* %arrayidx, align 4
181  %add = add nsw i32 %0, %r.06
182  %indvars.iv.next = add i64 %indvars.iv, 4
183  %1 = trunc i64 %indvars.iv.next to i32
184  %cmp = icmp slt i32 %1, 2048
185  br i1 %cmp, label %for.body, label %for.end
186
187for.end:                                          ; preds = %for.body
188  %add.lcssa = phi i32 [ %add, %for.body ]
189  ret i32 %add.lcssa
190
191}
192
193define i32 @koo2(i32* nocapture %a) nounwind uwtable readonly {
194; CHECK-LABEL: define {{[^@]+}}@koo2
195; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
196; CHECK-NEXT:  entry:
197; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
198; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
199; CHECK:       for.body:
200; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ -4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
201; CHECK-NEXT:    [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
202; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
203; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16
204; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[R_06]]
205; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4
206; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
207; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048
208; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
209; CHECK:       for.end:
210; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
211; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
212;
213entry:
214  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
215  br label %for.body
216
217for.body:                                         ; preds = %entry, %for.body
218  %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ]
219  %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
220  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
221  %0 = load i32, i32* %arrayidx, align 4
222  %add = add nsw i32 %0, %r.06
223  %indvars.iv.next = add i64 %indvars.iv, 4
224  %1 = trunc i64 %indvars.iv.next to i32
225  %cmp = icmp slt i32 %1, 2048
226  br i1 %cmp, label %for.body, label %for.end
227
228for.end:                                          ; preds = %for.body
229  %add.lcssa = phi i32 [ %add, %for.body ]
230  ret i32 %add.lcssa
231
232}
233
234define i32 @moo(i32* nocapture %a) nounwind uwtable {
235; CHECK-LABEL: define {{[^@]+}}@moo
236; CHECK-SAME: (i32* nocapture [[A:%.*]]) #1
237; CHECK-NEXT:  entry:
238; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
239; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[A]] to i8*
240; CHECK-NEXT:    tail call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP0]], i8 0, i64 64, i1 false)
241; CHECK-NEXT:    ret i32 undef
242;
243entry:
244  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
245  %0 = bitcast i32* %a to i8*
246  tail call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 0, i64 64, i1 false)
247  ret i32 undef
248
249}
250
251define i32 @moo2(i32* nocapture %a, i32* nocapture %b) nounwind uwtable {
252; CHECK-LABEL: define {{[^@]+}}@moo2
253; CHECK-SAME: (i32* nocapture [[A:%.*]], i32* nocapture [[B:%.*]]) #1
254; CHECK-NEXT:  entry:
255; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ]
256; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[B]], i64 128) ]
257; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[A]] to i8*
258; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[B]] to i8*
259; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 32 [[TMP0]], i8* align 128 [[TMP1]], i64 64, i1 false)
260; CHECK-NEXT:    ret i32 undef
261;
262entry:
263  call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)]
264  call void @llvm.assume(i1 true) ["align"(i32* %b, i64 128)]
265  %0 = bitcast i32* %a to i8*
266  %1 = bitcast i32* %b to i8*
267  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 64, i1 false)
268  ret i32 undef
269
270}
271
272declare void @llvm.assume(i1) nounwind
273
274declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
275declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
276
277