xref: /llvm-project/llvm/test/Transforms/LICM/hoist-bitcast-load.ll (revision 80e8f2beeb954f8c241897099bb01b24da400e8a)
1; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -S < %s | FileCheck %s
2; RUN: opt -S -passes=licm -verify-memoryssa < %s | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7; Make sure the basic alloca pointer hoisting works:
8; CHECK-LABEL: @test1
9; CHECK: load i32, ptr %c, align 4
10; CHECK: for.body:
11
12; Function Attrs: nounwind uwtable
13define void @test1(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 {
14entry:
15  %cmp6 = icmp sgt i32 %n, 0
16  %c = alloca i32
17  br i1 %cmp6, label %for.body, label %for.end
18
19for.body:                                         ; preds = %entry, %for.inc
20  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
21  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
22  %0 = load i32, ptr %arrayidx, align 4
23  %cmp1 = icmp sgt i32 %0, 0
24  br i1 %cmp1, label %if.then, label %for.inc
25
26if.then:                                          ; preds = %for.body
27  %1 = load i32, ptr %c, align 4
28  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv
29  %2 = load i32, ptr %arrayidx3, align 4
30  %mul = mul nsw i32 %2, %1
31  store i32 %mul, ptr %arrayidx, align 4
32  br label %for.inc
33
34for.inc:                                          ; preds = %for.body, %if.then
35  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
36  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
37  %exitcond = icmp eq i32 %lftr.wideiv, %n
38  br i1 %exitcond, label %for.end, label %for.body
39
40for.end:                                          ; preds = %for.inc, %entry
41  ret void
42}
43
44; Make sure the basic alloca pointer hoisting works through a bitcast to a
45; pointer to a smaller type:
46; CHECK-LABEL: @test2
47; CHECK: load i32, ptr %ca, align 4
48; CHECK: for.body:
49
50; Function Attrs: nounwind uwtable
51define void @test2(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 {
52entry:
53  %cmp6 = icmp sgt i32 %n, 0
54  %ca = alloca i64
55  br i1 %cmp6, label %for.body, label %for.end
56
57for.body:                                         ; preds = %entry, %for.inc
58  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
59  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
60  %0 = load i32, ptr %arrayidx, align 4
61  %cmp1 = icmp sgt i32 %0, 0
62  br i1 %cmp1, label %if.then, label %for.inc
63
64if.then:                                          ; preds = %for.body
65  %1 = load i32, ptr %ca, align 4
66  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv
67  %2 = load i32, ptr %arrayidx3, align 4
68  %mul = mul nsw i32 %2, %1
69  store i32 %mul, ptr %arrayidx, align 4
70  br label %for.inc
71
72for.inc:                                          ; preds = %for.body, %if.then
73  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
74  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
75  %exitcond = icmp eq i32 %lftr.wideiv, %n
76  br i1 %exitcond, label %for.end, label %for.body
77
78for.end:                                          ; preds = %for.inc, %entry
79  ret void
80}
81
82; Make sure the basic alloca pointer hoisting works through an addrspacecast
83; CHECK-LABEL: @test2_addrspacecast
84; CHECK: load i32, ptr addrspace(1) %c, align 4
85; CHECK: for.body:
86
87; Function Attrs: nounwind uwtable
88define void @test2_addrspacecast(ptr addrspace(1) nocapture %a, ptr addrspace(1) nocapture readonly %b, i32 %n) #0 {
89entry:
90  %cmp6 = icmp sgt i32 %n, 0
91  %ca = alloca i64
92  %c = addrspacecast ptr %ca to ptr addrspace(1)
93  br i1 %cmp6, label %for.body, label %for.end
94
95for.body:                                         ; preds = %entry, %for.inc
96  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
97  %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %a, i64 %indvars.iv
98  %0 = load i32, ptr addrspace(1) %arrayidx, align 4
99  %cmp1 = icmp sgt i32 %0, 0
100  br i1 %cmp1, label %if.then, label %for.inc
101
102if.then:                                          ; preds = %for.body
103  %1 = load i32, ptr addrspace(1) %c, align 4
104  %arrayidx3 = getelementptr inbounds i32, ptr addrspace(1) %b, i64 %indvars.iv
105  %2 = load i32, ptr addrspace(1) %arrayidx3, align 4
106  %mul = mul nsw i32 %2, %1
107  store i32 %mul, ptr addrspace(1) %arrayidx, align 4
108  br label %for.inc
109
110for.inc:                                          ; preds = %for.body, %if.then
111  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
112  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
113  %exitcond = icmp eq i32 %lftr.wideiv, %n
114  br i1 %exitcond, label %for.end, label %for.body
115
116for.end:                                          ; preds = %for.inc, %entry
117  ret void
118}
119
120; Make sure the basic alloca pointer hoisting works through a bitcast to a
121; pointer to a smaller type (where the bitcast also needs to be hoisted):
122; CHECK-LABEL: @test3
123; CHECK: load i32, ptr %ca, align 4
124; CHECK: for.body:
125
126; Function Attrs: nounwind uwtable
127define void @test3(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 {
128entry:
129  %cmp6 = icmp sgt i32 %n, 0
130  %ca = alloca i64
131  br i1 %cmp6, label %for.body, label %for.end
132
133for.body:                                         ; preds = %entry, %for.inc
134  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
135  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
136  %0 = load i32, ptr %arrayidx, align 4
137  %cmp1 = icmp sgt i32 %0, 0
138  br i1 %cmp1, label %if.then, label %for.inc
139
140if.then:                                          ; preds = %for.body
141  %1 = load i32, ptr %ca, align 4
142  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv
143  %2 = load i32, ptr %arrayidx3, align 4
144  %mul = mul nsw i32 %2, %1
145  store i32 %mul, ptr %arrayidx, align 4
146  br label %for.inc
147
148for.inc:                                          ; preds = %for.body, %if.then
149  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
150  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
151  %exitcond = icmp eq i32 %lftr.wideiv, %n
152  br i1 %exitcond, label %for.end, label %for.body
153
154for.end:                                          ; preds = %for.inc, %entry
155  ret void
156}
157
158; Make sure the basic alloca pointer hoisting does not happen through a bitcast
159; to a pointer to a larger type:
160; CHECK-LABEL: @test4
161; CHECK: for.body:
162; CHECK: load i32, ptr %ca, align 4
163
164; Function Attrs: nounwind uwtable
165define void @test4(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 {
166entry:
167  %cmp6 = icmp sgt i32 %n, 0
168  %ca = alloca i16
169  br i1 %cmp6, label %for.body, label %for.end
170
171for.body:                                         ; preds = %entry, %for.inc
172  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
173  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
174  %0 = load i32, ptr %arrayidx, align 4
175  %cmp1 = icmp sgt i32 %0, 0
176  br i1 %cmp1, label %if.then, label %for.inc
177
178if.then:                                          ; preds = %for.body
179  %1 = load i32, ptr %ca, align 4
180  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv
181  %2 = load i32, ptr %arrayidx3, align 4
182  %mul = mul nsw i32 %2, %1
183  store i32 %mul, ptr %arrayidx, align 4
184  br label %for.inc
185
186for.inc:                                          ; preds = %for.body, %if.then
187  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
188  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
189  %exitcond = icmp eq i32 %lftr.wideiv, %n
190  br i1 %exitcond, label %for.end, label %for.body
191
192for.end:                                          ; preds = %for.inc, %entry
193  ret void
194}
195
196; Don't crash on bitcasts to unsized types.
197; CHECK-LABEL: @test5
198; CHECK: for.body:
199; CHECK: load i32, ptr %ca, align 4
200
201%atype = type opaque
202
203; Function Attrs: nounwind uwtable
204define void @test5(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 {
205entry:
206  %cmp6 = icmp sgt i32 %n, 0
207  %ca = alloca i16
208  br i1 %cmp6, label %for.body, label %for.end
209
210for.body:                                         ; preds = %entry, %for.inc
211  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
212  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
213  %0 = load i32, ptr %arrayidx, align 4
214  %cmp1 = icmp sgt i32 %0, 0
215  br i1 %cmp1, label %if.then, label %for.inc
216
217if.then:                                          ; preds = %for.body
218  %1 = load i32, ptr %ca, align 4
219  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv
220  %2 = load i32, ptr %arrayidx3, align 4
221  %mul = mul nsw i32 %2, %1
222  store i32 %mul, ptr %arrayidx, align 4
223  br label %for.inc
224
225for.inc:                                          ; preds = %for.body, %if.then
226  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
227  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
228  %exitcond = icmp eq i32 %lftr.wideiv, %n
229  br i1 %exitcond, label %for.end, label %for.body
230
231for.end:                                          ; preds = %for.inc, %entry
232  ret void
233}
234
235attributes #0 = { nounwind uwtable }
236
237