xref: /llvm-project/llvm/test/Transforms/LoopStrengthReduce/ARM/2012-06-15-lsr-noaddrmode.ll (revision 055fb7795aa219a3d274d280ec9129784f169f56)
1; RUN: llc -O3 -mtriple=thumb-eabi -mcpu=cortex-a8 %s -o - -arm-atomic-cfg-tidy=0 | FileCheck %s
2;
3; LSR should only check for valid address modes when the IV user is a
4; memory address.
5; svn r158536, rdar://11635990
6;
7; Note that we still don't produce the best code here because we fail
8; to coalesce the IV. See <rdar://problem/11680670> [coalescer] IVs
9; need to be scheduled to expose coalescing.
10
11; LSR before the fix:
12;The chosen solution requires 4 regs, with addrec cost 1, plus 3 base adds, plus 2 setup cost:
13;  LSR Use: Kind=Special, Offsets={0}, all-fixups-outside-loop, widest fixup type: i32
14;    reg(%v3) + reg({0,+,-1}<%while.cond.i.i>) + imm(1)
15;  LSR Use: Kind=ICmpZero, Offsets={0}, widest fixup type: i32
16;    reg(%v3) + reg({0,+,-1}<%while.cond.i.i>)
17;  LSR Use: Kind=Address of i32, Offsets={0}, widest fixup type: i32*
18;    reg((-4 + (4 * %v3) + %v1)) + 4*reg({0,+,-1}<%while.cond.i.i>)
19;  LSR Use: Kind=Address of i32, Offsets={0}, widest fixup type: i32*
20;    reg((-4 + (4 * %v3) + %v4)) + 4*reg({0,+,-1}<%while.cond.i.i>)
21;  LSR Use: Kind=Special, Offsets={0}, all-fixups-outside-loop, widest fixup type: i32
22;    reg(%v3)
23;
24; LSR after the fix:
25;The chosen solution requires 4 regs, with addrec cost 1, plus 1 base add, plus 2 setup cost:
26;  LSR Use: Kind=Special, Offsets={0}, all-fixups-outside-loop, widest fixup type: i32
27;    reg({%v3,+,-1}<nsw><%while.cond.i.i>) + imm(1)
28;  LSR Use: Kind=ICmpZero, Offsets={0}, widest fixup type: i32
29;    reg({%v3,+,-1}<nsw><%while.cond.i.i>)
30;  LSR Use: Kind=Address of i32, Offsets={0}, widest fixup type: i32*
31;    reg((-4 + %v1)) + 4*reg({%v3,+,-1}<nsw><%while.cond.i.i>)
32;  LSR Use: Kind=Address of i32, Offsets={0}, widest fixup type: i32*
33;    reg((-4 + %v4)) + 4*reg({%v3,+,-1}<nsw><%while.cond.i.i>)
34;  LSR Use: Kind=Special, Offsets={0}, all-fixups-outside-loop, widest fixup type: i32
35;    reg(%v3)
36
37
38%s = type { ptr }
39
40@ncol = external global i32, align 4
41
42declare ptr @getptr() nounwind
43declare ptr @getstruct() nounwind
44
45; CHECK: @main
46; Check that the loop preheader contains no address computation.
47; CHECK: %while.cond.i.i
48; CHECK-NOT: add{{.*}}lsl
49; CHECK: ldr{{.*}}lsl #2
50; CHECK: ldr{{.*}}lsl #2
51define i32 @main() nounwind ssp {
52entry:
53  %v0 = load i32, ptr @ncol, align 4
54  %v1 = tail call ptr @getptr() nounwind
55  %cmp10.i = icmp eq i32 %v0, 0
56  br label %while.cond.outer
57
58while.cond.outer:
59  %call18 = tail call ptr @getstruct() nounwind
60  br label %while.cond
61
62while.cond:
63  %cmp20 = icmp eq ptr %v1, null
64  br label %while.body
65
66while.body:
67  %v3 = load i32, ptr @ncol, align 4
68  br label %end_of_chain
69
70end_of_chain:
71  %v4 = load ptr, ptr %call18, align 4
72  br label %while.cond.i.i
73
74while.cond.i.i:
75  %counter.0.i.i = phi i32 [ %v3, %end_of_chain ], [ %dec.i.i, %land.rhs.i.i ]
76  %dec.i.i = add nsw i32 %counter.0.i.i, -1
77  %tobool.i.i = icmp eq i32 %counter.0.i.i, 0
78  br i1 %tobool.i.i, label %where.exit, label %land.rhs.i.i
79
80land.rhs.i.i:
81  %arrayidx.i.i = getelementptr inbounds i32, ptr %v4, i32 %dec.i.i
82  %v5 = load i32, ptr %arrayidx.i.i, align 4
83  %arrayidx1.i.i = getelementptr inbounds i32, ptr %v1, i32 %dec.i.i
84  %v6 = load i32, ptr %arrayidx1.i.i, align 4
85  %cmp.i.i = icmp eq i32 %v5, %v6
86  br i1 %cmp.i.i, label %while.cond.i.i, label %equal_data.exit.i
87
88equal_data.exit.i:
89  ret i32 %counter.0.i.i
90
91where.exit:
92  br label %while.end.i
93
94while.end.i:
95  ret i32 %v3
96}
97