llvm.org GIT mirror llvm / 003fe85
[SCEV] Enhance SCEVFindUnsafe for division This patch allows SCEVFindUnsafe algorithm to tread division by any non-positive value as safe. Previously, it could only recognize non-zero constants. Differential Revision: https://reviews.llvm.org/D39228 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316568 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 1 year, 11 months ago
2 changed file(s) with 40 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
22492249 // only needed when the expression includes some subexpression that is not IV
22502250 // derived.
22512251 //
2252 // Currently, we only allow division by a nonzero constant here. If this is
2253 // inadequate, we could easily allow division by SCEVUnknown by using
2254 // ValueTracking to check isKnownNonZero().
2255 //
22562252 // We cannot generally expand recurrences unless the step dominates the loop
22572253 // header. The expander handles the special case of affine recurrences by
22582254 // scaling the recurrence outside the loop, but this technique isn't generally
22672263
22682264 bool follow(const SCEV *S) {
22692265 if (const SCEVUDivExpr *D = dyn_cast(S)) {
2270 const SCEVConstant *SC = dyn_cast(D->getRHS());
2271 if (!SC || SC->getValue()->isZero()) {
2266 if (!SE.isKnownNonZero(D->getRHS())) {
22722267 IsUnsafe = true;
22732268 return false;
22742269 }
2275 }
2276 if (const SCEVAddRecExpr *AR = dyn_cast(S)) {
2270 } else if (const SCEVAddRecExpr *AR = dyn_cast(S)) {
22772271 const SCEV *Step = AR->getStepRecurrence(SE);
22782272 if (!AR->isAffine() && !SE.dominates(Step, AR->getLoop()->getHeader())) {
22792273 IsUnsafe = true;
129129 ; IndVars doesn't emit a udiv in for.body.preheader since SCEVExpander::expand will
130130 ; find out there's already a udiv in the original code.
131131
132 ; CHECK-LABEL: @foo(
132 ; CHECK-LABEL: @foo_01(
133133 ; CHECK: for.body.preheader:
134134 ; CHECK-NOT: udiv
135135
136 define void @foo(double* %p, i64 %n) nounwind {
136 define void @foo_01(double* %p, i64 %n) nounwind {
137137 entry:
138138 %div0 = udiv i64 %n, 7 ; [#uses=1]
139139 %div1 = add i64 %div0, 1
159159 for.end: ; preds = %for.end.loopexit, %entry
160160 ret void
161161 }
162
163 ; Same as foo_01, but we divide by non-constant value.
164
165 ; CHECK-LABEL: @foo_02(
166 ; CHECK: for.body.preheader:
167 ; CHECK-NOT: udiv
168
169 define void @foo_02(double* %p, i64 %n, i64* %lp) nounwind {
170 entry:
171 %denom = load i64, i64* %lp, align 4, !range !0
172 %div0 = udiv i64 %n, %denom ; [#uses=1]
173 %div1 = add i64 %div0, 1
174 %cmp2 = icmp ult i64 0, %div1 ; [#uses=1]
175 br i1 %cmp2, label %for.body.preheader, label %for.end
176
177 for.body.preheader: ; preds = %entry
178 br label %for.body
179
180 for.body: ; preds = %for.body.preheader, %for.body
181 %i.03 = phi i64 [ %inc, %for.body ], [ 0, %for.body.preheader ] ; [#uses=2]
182 %arrayidx = getelementptr inbounds double, double* %p, i64 %i.03 ; [#uses=1]
183 store double 0.000000e+00, double* %arrayidx
184 %inc = add i64 %i.03, 1 ; [#uses=2]
185 %divx = udiv i64 %n, %denom ; [#uses=1]
186 %div = add i64 %divx, 1
187 %cmp = icmp ult i64 %inc, %div ; [#uses=1]
188 br i1 %cmp, label %for.body, label %for.end.loopexit
189
190 for.end.loopexit: ; preds = %for.body
191 br label %for.end
192
193 for.end: ; preds = %for.end.loopexit, %entry
194 ret void
195 }
196
197 !0 = !{i64 1, i64 10}