1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; REQUIRES: aarch64-registered-target
4 ; RUN: opt < %s -licm -S | FileCheck %s
6 target triple = "aarch64--linux-gnueabi"
8 define i8** @test1(i32 %j, i8** readonly %P, i8* readnone %Q) {
11 ; CHECK-NEXT: [[CMP0:%.*]] = icmp slt i32 0, [[J:%.*]]
12 ; CHECK-NEXT: br i1 [[CMP0]], label [[FOR_BODY_LR_PH:%.*]], label [[RETURN:%.*]]
13 ; CHECK: for.body.lr.ph:
14 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
16 ; CHECK-NEXT: [[P_ADDR:%.*]] = phi i8** [ [[P:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ARRAYIDX0:%.*]], [[IF_END:%.*]] ]
17 ; CHECK-NEXT: [[I0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[I_ADD:%.*]], [[IF_END]] ]
18 ; CHECK-NEXT: [[I0_EXT:%.*]] = sext i32 [[I0]] to i64
19 ; CHECK-NEXT: [[ARRAYIDX0]] = getelementptr inbounds i8*, i8** [[P_ADDR]], i64 [[I0_EXT]]
20 ; CHECK-NEXT: [[L0:%.*]] = load i8*, i8** [[ARRAYIDX0]], align 8
21 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8* [[L0]], [[Q:%.*]]
22 ; CHECK-NEXT: br i1 [[CMP1]], label [[LOOPEXIT0:%.*]], label [[IF_END]]
24 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8*, i8** [[ARRAYIDX0]], i64 1
25 ; CHECK-NEXT: [[L1:%.*]] = load i8*, i8** [[ARRAYIDX1]], align 8
26 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i8* [[L1]], [[Q]]
27 ; CHECK-NEXT: [[I_ADD]] = add nsw i32 [[I0]], 2
28 ; CHECK-NEXT: br i1 [[CMP4]], label [[LOOPEXIT1:%.*]], label [[FOR_BODY]]
30 ; CHECK-NEXT: [[P1:%.*]] = phi i8** [ [[ARRAYIDX0]], [[FOR_BODY]] ]
31 ; CHECK-NEXT: br label [[RETURN]]
33 ; CHECK-NEXT: [[ARRAYIDX0_LCSSA:%.*]] = phi i8** [ [[ARRAYIDX0]], [[IF_END]] ]
34 ; CHECK-NEXT: [[ARRAYIDX1_LE:%.*]] = getelementptr inbounds i8*, i8** [[ARRAYIDX0_LCSSA]], i64 1
35 ; CHECK-NEXT: br label [[RETURN]]
37 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8** [ [[P1]], [[LOOPEXIT0]] ], [ [[ARRAYIDX1_LE]], [[LOOPEXIT1]] ], [ null, [[ENTRY:%.*]] ]
38 ; CHECK-NEXT: ret i8** [[RETVAL_0]]
41 %cmp0 = icmp slt i32 0, %j
42 br i1 %cmp0, label %for.body.lr.ph, label %return
48 %P.addr = phi i8** [ %P, %for.body.lr.ph ], [ %arrayidx0, %if.end ]
49 %i0 = phi i32 [ 0, %for.body.lr.ph ], [ %i.add, %if.end]
51 %i0.ext = sext i32 %i0 to i64
52 %arrayidx0 = getelementptr inbounds i8*, i8** %P.addr, i64 %i0.ext
53 %l0 = load i8*, i8** %arrayidx0, align 8
54 %cmp1 = icmp ugt i8* %l0, %Q
55 br i1 %cmp1, label %loopexit0, label %if.end
57 if.end: ; preds = %for.body
58 %arrayidx1 = getelementptr inbounds i8*, i8** %arrayidx0, i64 1
59 %l1 = load i8*, i8** %arrayidx1, align 8
60 %cmp4 = icmp ugt i8* %l1, %Q
61 %i.add = add nsw i32 %i0, 2
62 br i1 %cmp4, label %loopexit1, label %for.body
65 %p1 = phi i8** [%arrayidx0, %for.body]
69 %p2 = phi i8** [%arrayidx1, %if.end]
73 %retval.0 = phi i8** [ %p1, %loopexit0 ], [%p2, %loopexit1], [ null, %entry ]
77 define i8** @test2(i32 %j, i8** readonly %P, i8* readnone %Q) {
78 ; CHECK-LABEL: @test2(
80 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
82 ; CHECK-NEXT: [[I_ADDR_0:%.*]] = phi i32 [ [[ADD:%.*]], [[IF_END:%.*]] ]
83 ; CHECK-NEXT: [[P_ADDR_0:%.*]] = phi i8** [ [[ADD_PTR:%.*]], [[IF_END]] ]
84 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_ADDR_0]], [[J:%.*]]
85 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[LOOPEXIT0:%.*]]
87 ; CHECK-NEXT: [[P_ADDR:%.*]] = phi i8** [ [[P:%.*]], [[ENTRY:%.*]] ], [ [[P_ADDR_0]], [[FOR_COND:%.*]] ]
88 ; CHECK-NEXT: [[I_ADDR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I_ADDR_0]], [[FOR_COND]] ]
89 ; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I_ADDR]] to i64
90 ; CHECK-NEXT: [[ADD_PTR]] = getelementptr inbounds i8*, i8** [[P_ADDR]], i64 [[IDX_EXT]]
91 ; CHECK-NEXT: [[L0:%.*]] = load i8*, i8** [[ADD_PTR]], align 8
92 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8* [[L0]], [[Q:%.*]]
93 ; CHECK-NEXT: br i1 [[CMP1]], label [[LOOPEXIT1:%.*]], label [[IF_END]]
95 ; CHECK-NEXT: [[ADD_I:%.*]] = add i32 [[I_ADDR]], 1
96 ; CHECK-NEXT: [[IDX2_EXT:%.*]] = sext i32 [[ADD_I]] to i64
97 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8*, i8** [[ADD_PTR]], i64 [[IDX2_EXT]]
98 ; CHECK-NEXT: [[L1:%.*]] = load i8*, i8** [[ARRAYIDX2]], align 8
99 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8* [[L1]], [[Q]]
100 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD_I]], 1
101 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOPEXIT2:%.*]], label [[FOR_COND]]
103 ; CHECK-NEXT: [[P0:%.*]] = phi i8** [ null, [[FOR_COND]] ]
104 ; CHECK-NEXT: br label [[RETURN:%.*]]
106 ; CHECK-NEXT: [[P1:%.*]] = phi i8** [ [[ADD_PTR]], [[FOR_BODY]] ]
107 ; CHECK-NEXT: br label [[RETURN]]
109 ; CHECK-NEXT: [[IDX2_EXT_LCSSA:%.*]] = phi i64 [ [[IDX2_EXT]], [[IF_END]] ]
110 ; CHECK-NEXT: [[ADD_PTR_LCSSA:%.*]] = phi i8** [ [[ADD_PTR]], [[IF_END]] ]
111 ; CHECK-NEXT: [[ARRAYIDX2_LE:%.*]] = getelementptr inbounds i8*, i8** [[ADD_PTR_LCSSA]], i64 [[IDX2_EXT_LCSSA]]
112 ; CHECK-NEXT: br label [[RETURN]]
114 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8** [ [[P1]], [[LOOPEXIT1]] ], [ [[ARRAYIDX2_LE]], [[LOOPEXIT2]] ], [ [[P0]], [[LOOPEXIT0]] ]
115 ; CHECK-NEXT: ret i8** [[RETVAL_0]]
121 %i.addr.0 = phi i32 [ %add, %if.end ]
122 %P.addr.0 = phi i8** [ %add.ptr, %if.end ]
123 %cmp = icmp slt i32 %i.addr.0, %j
124 br i1 %cmp, label %for.body, label %loopexit0
127 %P.addr = phi i8** [ %P, %entry ], [ %P.addr.0, %for.cond ]
128 %i.addr = phi i32 [ 0, %entry ], [ %i.addr.0, %for.cond ]
130 %idx.ext = sext i32 %i.addr to i64
131 %add.ptr = getelementptr inbounds i8*, i8** %P.addr, i64 %idx.ext
132 %l0 = load i8*, i8** %add.ptr, align 8
134 %cmp1 = icmp ugt i8* %l0, %Q
135 br i1 %cmp1, label %loopexit1, label %if.end
138 %add.i = add i32 %i.addr, 1
139 %idx2.ext = sext i32 %add.i to i64
140 %arrayidx2 = getelementptr inbounds i8*, i8** %add.ptr, i64 %idx2.ext
141 %l1 = load i8*, i8** %arrayidx2, align 8
142 %cmp2 = icmp ugt i8* %l1, %Q
143 %add = add nsw i32 %add.i, 1
144 br i1 %cmp2, label %loopexit2, label %for.cond
147 %p0 = phi i8** [ null, %for.cond ]
151 %p1 = phi i8** [ %add.ptr, %for.body ]
155 %p2 = phi i8** [ %arrayidx2, %if.end ]
159 %retval.0 = phi i8** [ %p1, %loopexit1 ], [ %p2, %loopexit2 ], [ %p0, %loopexit0 ]
164 define i8** @test3(i64 %j, i8** readonly %P, i8* readnone %Q) {
165 ; CHECK-LABEL: @test3(
167 ; CHECK-NEXT: [[CMP0:%.*]] = icmp slt i64 0, [[J:%.*]]
168 ; CHECK-NEXT: br i1 [[CMP0]], label [[FOR_BODY_LR_PH:%.*]], label [[RETURN:%.*]]
169 ; CHECK: for.body.lr.ph:
170 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
172 ; CHECK-NEXT: [[P_ADDR:%.*]] = phi i8** [ [[P:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ARRAYIDX0:%.*]], [[IF_END:%.*]] ]
173 ; CHECK-NEXT: [[I0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[I_ADD:%.*]], [[IF_END]] ]
174 ; CHECK-NEXT: [[I0_EXT:%.*]] = sext i32 [[I0]] to i64
175 ; CHECK-NEXT: [[ARRAYIDX0]] = getelementptr inbounds i8*, i8** [[P_ADDR]], i64 [[I0_EXT]]
176 ; CHECK-NEXT: [[L0:%.*]] = load i8*, i8** [[ARRAYIDX0]], align 8
177 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8* [[L0]], [[Q:%.*]]
178 ; CHECK-NEXT: br i1 [[CMP1]], label [[LOOPEXIT0:%.*]], label [[IF_END]]
180 ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[I0_EXT]], 1
181 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[ADD]] to i32
182 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8*, i8** [[P_ADDR]], i32 [[TRUNC]]
183 ; CHECK-NEXT: [[L1:%.*]] = load i8*, i8** [[ARRAYIDX1]], align 8
184 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i8* [[L1]], [[Q]]
185 ; CHECK-NEXT: [[I_ADD]] = add nsw i32 [[I0]], 2
186 ; CHECK-NEXT: br i1 [[CMP4]], label [[LOOPEXIT1:%.*]], label [[FOR_BODY]]
188 ; CHECK-NEXT: [[P1:%.*]] = phi i8** [ [[ARRAYIDX0]], [[FOR_BODY]] ]
189 ; CHECK-NEXT: br label [[RETURN]]
191 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i64 [ [[ADD]], [[IF_END]] ]
192 ; CHECK-NEXT: [[P_ADDR_LCSSA:%.*]] = phi i8** [ [[P_ADDR]], [[IF_END]] ]
193 ; CHECK-NEXT: [[TRUNC_LE:%.*]] = trunc i64 [[ADD_LCSSA]] to i32
194 ; CHECK-NEXT: [[ARRAYIDX1_LE:%.*]] = getelementptr inbounds i8*, i8** [[P_ADDR_LCSSA]], i32 [[TRUNC_LE]]
195 ; CHECK-NEXT: call void @dummy(i32 [[TRUNC_LE]])
196 ; CHECK-NEXT: br label [[RETURN]]
198 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8** [ [[P1]], [[LOOPEXIT0]] ], [ [[ARRAYIDX1_LE]], [[LOOPEXIT1]] ], [ null, [[ENTRY:%.*]] ]
199 ; CHECK-NEXT: ret i8** [[RETVAL_0]]
202 %cmp0 = icmp slt i64 0, %j
203 br i1 %cmp0, label %for.body.lr.ph, label %return
209 %P.addr = phi i8** [ %P, %for.body.lr.ph ], [ %arrayidx0, %if.end ]
210 %i0 = phi i32 [ 0, %for.body.lr.ph ], [ %i.add, %if.end]
212 %i0.ext = sext i32 %i0 to i64
213 %arrayidx0 = getelementptr inbounds i8*, i8** %P.addr, i64 %i0.ext
214 %l0 = load i8*, i8** %arrayidx0, align 8
215 %cmp1 = icmp ugt i8* %l0, %Q
216 br i1 %cmp1, label %loopexit0, label %if.end
218 if.end: ; preds = %for.body
219 %add = add i64 %i0.ext, 1
220 %trunc = trunc i64 %add to i32
221 %arrayidx1 = getelementptr inbounds i8*, i8** %P.addr, i32 %trunc
222 %l1 = load i8*, i8** %arrayidx1, align 8
223 %cmp4 = icmp ugt i8* %l1, %Q
224 %i.add = add nsw i32 %i0, 2
225 br i1 %cmp4, label %loopexit1, label %for.body
228 %p1 = phi i8** [%arrayidx0, %for.body]
232 %p2 = phi i8** [%arrayidx1, %if.end]
233 call void @dummy(i32 %trunc)
237 %retval.0 = phi i8** [ %p1, %loopexit0 ], [%p2, %loopexit1], [ null, %entry ]
241 declare void @dummy(i32)