llvm.org GIT mirror llvm / d9b36e1
Recognize n/1 in the SCEV divide function n/1 generates a quotient equal to n and a remainder of 0. If this case is not recognized, then the SCEV divide() function can return a remainder that is greater than or equal to the denominator, which means the delinearized subscripts for the test case will be incorrect. Differential Revision: http://reviews.llvm.org/D9003 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235311 91177308-0d34-0410-b5e6-96231b3b80d8 Brendon Cahoon 5 years ago
2 changed file(s) with 77 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
721721
722722 if (Numerator->isZero()) {
723723 *Quotient = D.Zero;
724 *Remainder = D.Zero;
725 return;
726 }
727
728 // A simple case when N/1. The quotient is N.
729 if (Denominator->isOne()) {
730 *Quotient = Numerator;
724731 *Remainder = D.Zero;
725732 return;
726733 }
0 ; RUN: opt < %s -analyze -delinearize | FileCheck %s
1
2 target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32"
3
4 ; Check that division by 1 can be delinearized.
5 ;
6 ; void test1(unsigned char *dst, int stride, int bs) {
7 ; for (int r = bs; r >= 0; --r)
8 ; for (int c = 0; c < bs; ++c)
9 ; dst[r * stride + c] = dst[(r + 1) * stride + c - 1];
10 ; }
11
12 ; AddRec: {{(-1 + ((1 + %bs) * %stride)),+,(-1 * %stride)}<%for.cond1.preheader>,+,1}<%for.body3>
13 ; CHECK: Inst: %0 = load i8, i8* %arrayidx, align 1
14 ; CHECK: Base offset: %dst
15 ; CHECK: ArrayDecl[UnknownSize][%stride] with elements of 1 bytes.
16 ; CHECK: ArrayRef[{(1 + %bs),+,-1}<%for.cond1.preheader>][{-1,+,1}<%for.body3>]
17
18 ; AddRec: {{(%stride * %bs),+,(-1 * %stride)}<%for.cond1.preheader>,+,1}<%for.body3>
19 ; CHECK: Inst: store i8 %0, i8* %arrayidx7, align 1
20 ; CHECK: Base offset: %dst
21 ; CHECK: ArrayDecl[UnknownSize][%stride] with elements of 1 bytes.
22 ; CHECK: ArrayRef[{%bs,+,-1}<%for.cond1.preheader>][{0,+,1}<%for.body3>]
23
24 define void @test(i8* nocapture %dst, i32 %stride, i32 %bs) {
25 entry:
26 %cmp20 = icmp sgt i32 %bs, -1
27 br i1 %cmp20, label %for.cond1.preheader.lr.ph, label %for.end9
28
29 for.cond1.preheader.lr.ph:
30 %cmp218 = icmp slt i32 0, %bs
31 br label %for.cond1.preheader
32
33 for.cond1.preheader:
34 %r.021 = phi i32 [ %bs, %for.cond1.preheader.lr.ph ], [ %dec, %for.inc8 ]
35 br i1 %cmp218, label %for.body3.lr.ph, label %for.inc8
36
37 for.body3.lr.ph:
38 %add = add nsw i32 %r.021, 1
39 %mul = mul nsw i32 %add, %stride
40 %add4 = add i32 %mul, -1
41 %mul5 = mul nsw i32 %r.021, %stride
42 br label %for.body3
43
44 for.body3:
45 %c.019 = phi i32 [ 0, %for.body3.lr.ph ], [ %inc, %for.body3 ]
46 %sub = add i32 %add4, %c.019
47 %arrayidx = getelementptr inbounds i8, i8* %dst, i32 %sub
48 %0 = load i8, i8* %arrayidx, align 1
49 %add6 = add nsw i32 %c.019, %mul5
50 %arrayidx7 = getelementptr inbounds i8, i8* %dst, i32 %add6
51 store i8 %0, i8* %arrayidx7, align 1
52 %inc = add nsw i32 %c.019, 1
53 %cmp2 = icmp slt i32 %inc, %bs
54 br i1 %cmp2, label %for.body3, label %for.cond1.for.inc8_crit_edge
55
56 for.cond1.for.inc8_crit_edge:
57 br label %for.inc8
58
59 for.inc8:
60 %dec = add nsw i32 %r.021, -1
61 %cmp = icmp sgt i32 %dec, -1
62 br i1 %cmp, label %for.cond1.preheader, label %for.cond.for.end9_crit_edge
63
64 for.cond.for.end9_crit_edge:
65 br label %for.end9
66
67 for.end9:
68 ret void
69 }