llvm.org GIT mirror llvm / 4a1169e
[RLEV] Rewrite loop exit values for multiple exit loops w/o overall loop exit count We already supported rewriting loop exit values for multiple exit loops, but if any of the loop exits were not computable, we gave up on all loop exit values. This patch generalizes the existing code to handle individual computable loop exits where possible. As discussed in the review, this is a starting point for figuring out a better API. The code is a bit ugly, but getting it in lets us test as we go. Differential Revision: https://reviews.llvm.org/D65544 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368898 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames a month ago
3 changed file(s) with 188 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
627627
628628 // Okay, this instruction has a user outside of the current loop
629629 // and varies predictably *inside* the loop. Evaluate the value it
630 // contains when the loop exits, if possible.
630 // contains when the loop exits, if possible. We prefer to start with
631 // expressions which are true for all exits (so as to maximize
632 // expression reuse by the SCEVExpander), but resort to per-exit
633 // evaluation if that fails.
631634 const SCEV *ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
632635 if (isa(ExitValue) ||
633636 !SE->isLoopInvariant(ExitValue, L) ||
634 !isSafeToExpand(ExitValue, *SE))
635 continue;
636
637 !isSafeToExpand(ExitValue, *SE)) {
638 // TODO: This should probably be sunk into SCEV in some way; maybe a
639 // getSCEVForExit(SCEV*, L, ExitingBB)? It can be generalized for
640 // most SCEV expressions and other recurrence types (e.g. shift
641 // recurrences). Is there existing code we can reuse?
642 const SCEV *ExitCount = SE->getExitCount(L, PN->getIncomingBlock(i));
643 if (isa(ExitCount))
644 continue;
645 if (auto *AddRec = dyn_cast(SE->getSCEV(Inst)))
646 ExitValue = AddRec->evaluateAtIteration(ExitCount, *SE);
647 if (isa(ExitValue) ||
648 !SE->isLoopInvariant(ExitValue, L) ||
649 !isSafeToExpand(ExitValue, *SE))
650 continue;
651 }
652
637653 // Computing the value outside of the loop brings no benefit if it is
638654 // definitely used inside the loop in a way which can not be optimized
639655 // away. Avoid doing so unless we know we have a value which computes
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -indvars < %s | FileCheck %s
2 target datalayout = "n8:16:32:64"
3 @G = external global i32
4
5 ; Basic case where we know the value of an induction variable along one
6 ; exit edge, but not another.
7 define i32 @test(i32 %n) {
8 ; CHECK-LABEL: @test(
9 ; CHECK-NEXT: entry:
10 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
11 ; CHECK-NEXT: br label [[HEADER:%.*]]
12 ; CHECK: header:
13 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
14 ; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* @G
15 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[V]], 0
16 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT1:%.*]]
17 ; CHECK: latch:
18 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
19 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
20 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[HEADER]], label [[EXIT2:%.*]]
21 ; CHECK: exit1:
22 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[HEADER]] ]
23 ; CHECK-NEXT: ret i32 [[IV_LCSSA]]
24 ; CHECK: exit2:
25 ; CHECK-NEXT: ret i32 [[N]]
26 ;
27 entry:
28 br label %header
29 header:
30 %iv = phi i32 [0, %entry], [%iv.next, %latch]
31 %v = load volatile i32, i32* @G
32 %cmp1 = icmp eq i32 %v, 0
33 br i1 %cmp1, label %latch, label %exit1
34
35 latch:
36 %iv.next = add i32 %iv, 1
37 %cmp2 = icmp ult i32 %iv, %n
38 br i1 %cmp2, label %header, label %exit2
39 exit1:
40 ret i32 %iv
41 exit2:
42 ret i32 %iv
43 }
44
45 define i32 @test2(i32 %n) {
46 ; CHECK-LABEL: @test2(
47 ; CHECK-NEXT: entry:
48 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
49 ; CHECK-NEXT: br label [[HEADER:%.*]]
50 ; CHECK: header:
51 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
52 ; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* @G
53 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[V]], 0
54 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT1:%.*]]
55 ; CHECK: latch:
56 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
57 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
58 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[HEADER]], label [[EXIT2:%.*]]
59 ; CHECK: exit1:
60 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[HEADER]] ]
61 ; CHECK-NEXT: ret i32 [[IV_LCSSA]]
62 ; CHECK: exit2:
63 ; CHECK-NEXT: ret i32 [[TMP0]]
64 ;
65 entry:
66 br label %header
67 header:
68 %iv = phi i32 [0, %entry], [%iv.next, %latch]
69 %v = load volatile i32, i32* @G
70 %cmp1 = icmp eq i32 %v, 0
71 br i1 %cmp1, label %latch, label %exit1
72
73 latch:
74 %iv.next = add i32 %iv, 1
75 %cmp2 = icmp ult i32 %iv, %n
76 br i1 %cmp2, label %header, label %exit2
77 exit1:
78 ret i32 %iv
79 exit2:
80 ret i32 %iv.next
81 }
82
83 ; TODO: Generalize the code to handle other SCEV expressions
84 define i32 @test3(i32 %n) {
85 ; CHECK-LABEL: @test3(
86 ; CHECK-NEXT: entry:
87 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
88 ; CHECK-NEXT: br label [[HEADER:%.*]]
89 ; CHECK: header:
90 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
91 ; CHECK-NEXT: [[EXPR:%.*]] = udiv i32 [[IV]], 5
92 ; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* @G
93 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[V]], 0
94 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT1:%.*]]
95 ; CHECK: latch:
96 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
97 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
98 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[HEADER]], label [[EXIT2:%.*]]
99 ; CHECK: exit1:
100 ; CHECK-NEXT: [[EXPR_LCSSA:%.*]] = phi i32 [ [[EXPR]], [[HEADER]] ]
101 ; CHECK-NEXT: ret i32 [[EXPR_LCSSA]]
102 ; CHECK: exit2:
103 ; CHECK-NEXT: [[EXPR_LCSSA1:%.*]] = phi i32 [ [[EXPR]], [[LATCH]] ]
104 ; CHECK-NEXT: ret i32 [[EXPR_LCSSA1]]
105 ;
106 entry:
107 br label %header
108 header:
109 %iv = phi i32 [0, %entry], [%iv.next, %latch]
110 %expr = udiv i32 %iv, 5
111 %v = load volatile i32, i32* @G
112 %cmp1 = icmp eq i32 %v, 0
113 br i1 %cmp1, label %latch, label %exit1
114
115 latch:
116 %iv.next = add i32 %iv, 1
117 %cmp2 = icmp ult i32 %iv, %n
118 br i1 %cmp2, label %header, label %exit2
119 exit1:
120 ret i32 %expr
121 exit2:
122 ret i32 %expr
123 }
124
125
126 ; A slightly more real example where we're searching for either a) the first
127 ; non-zero element, or b) the end of a memory region.
128 define i32 @bounded_find(i32 %n) {
129 ; CHECK-LABEL: @bounded_find(
130 ; CHECK-NEXT: entry:
131 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
132 ; CHECK-NEXT: br label [[HEADER:%.*]]
133 ; CHECK: header:
134 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
135 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* @G, i32 [[IV]]
136 ; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[ADDR]]
137 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[V]], 0
138 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT1:%.*]]
139 ; CHECK: latch:
140 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
141 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
142 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[HEADER]], label [[EXIT2:%.*]]
143 ; CHECK: exit1:
144 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[HEADER]] ]
145 ; CHECK-NEXT: ret i32 [[IV_LCSSA]]
146 ; CHECK: exit2:
147 ; CHECK-NEXT: ret i32 [[N]]
148 ;
149 entry:
150 br label %header
151 header:
152 %iv = phi i32 [0, %entry], [%iv.next, %latch]
153 %addr = getelementptr i32, i32* @G, i32 %iv
154 %v = load i32, i32* %addr
155 %cmp1 = icmp eq i32 %v, 0
156 br i1 %cmp1, label %latch, label %exit1
157
158 latch:
159 %iv.next = add i32 %iv, 1
160 %cmp2 = icmp ult i32 %iv, %n
161 br i1 %cmp2, label %header, label %exit2
162 exit1:
163 ret i32 %iv
164 exit2:
165 ret i32 %iv
166 }
183183 ; CHECK: for.body:
184184 ; CHECK: %b.03 = phi i32 [ 0, %entry ], [ %add, %for.cond ]
185185 ; CHECK: return:
186 ; CHECK: %b.03.lcssa = phi i32 [ %b.03, %for.body ], [ 0, %for.cond ]
186 ; CHECK: %b.03.lcssa = phi i32 [ 8, %for.body ], [ 0, %for.cond ]
187187 define void @nsw_latch(i32* %a) nounwind {
188188 entry:
189189 br label %for.body