• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-delicm -analyze < %s | FileCheck %s -match-full-lines
2;
3; Load (but not store) of A[j] hoisted, reduction not written in all iterations.
4; FIXME: %join is not mapped because the MemoryKind::Value mapping does not
5;        encompass all iterations (last iteration is unused)
6;
7;    void func(double *A) {
8;      for (int j = 0; j < 2; j += 1) { /* outer */
9;        double phi = 0.0;
10;        for (int i = 0; i < 4; i += 1) { /* reduction */
11;          if (i != 2) {
12;            phi += 4.2;
13;            A[j] = phi;
14;          }
15;        }
16;      }
17;    }
18;
19define void @func(double* noalias nonnull %A) {
20entry:
21  br label %outer.preheader
22
23outer.preheader:
24  br label %outer.for
25
26outer.for:
27  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
28  %j.cmp = icmp slt i32 %j, 2
29  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
30
31
32    reduction.preheader:
33      %A_idx = getelementptr inbounds double, double* %A, i32 %j
34      %init = load double, double* %A_idx
35      br label %reduction.for
36
37    reduction.for:
38      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
39      %phi = phi double [%init, %reduction.preheader], [%join, %reduction.inc]
40      br label %body
41
42
43
44        body:
45          %cond = icmp ne i32 %i, 2
46          br i1 %cond, label %body_true, label %body_join
47
48        body_true:
49          %add = fadd double %phi, 4.2
50          store double %add, double* %A_idx
51          br label %body_join
52
53        body_join:
54          %join = phi double [%phi, %body], [%add, %body_true]
55          br label %reduction.inc
56
57
58
59    reduction.inc:
60      %i.inc = add nuw nsw i32 %i, 1
61      %i.cmp = icmp slt i32 %i.inc, 4
62      br i1 %i.cmp, label %reduction.for, label %reduction.exit
63
64    reduction.exit:
65      br label %outer.inc
66
67
68
69outer.inc:
70  %j.inc = add nuw nsw i32 %j, 1
71  br label %outer.for
72
73outer.exit:
74  br label %return
75
76return:
77  ret void
78}
79
80
81; CHECK: Statistics {
82; CHECK:     Compatible overwrites: 1
83; CHECK:     Overwrites mapped to:  1
84; CHECK:     Value scalars mapped:  1
85; CHECK:     PHI scalars mapped:    1
86; CHECK: }
87
88; CHECK-NEXT: After accesses {
89; CHECK-NEXT:     Stmt_reduction_preheader
90; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
91; CHECK-NEXT:                 { Stmt_reduction_preheader[i0] -> MemRef_A[i0] };
92; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
93; CHECK-NEXT:                 { Stmt_reduction_preheader[i0] -> MemRef_phi__phi[] };
94; CHECK-NEXT:            new: { Stmt_reduction_preheader[i0] -> MemRef_A[i0] };
95; CHECK-NEXT:     Stmt_reduction_for
96; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 1]
97; CHECK-NEXT:                 { Stmt_reduction_for[i0, i1] -> MemRef_phi__phi[] };
98; CHECK-NEXT:            new: { Stmt_reduction_for[i0, i1] -> MemRef_A[i0] };
99; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
100; CHECK-NEXT:                 { Stmt_reduction_for[i0, i1] -> MemRef_phi[] };
101; CHECK-NEXT:            new: { Stmt_reduction_for[i0, i1] -> MemRef_A[i0] };
102; CHECK-NEXT:     Stmt_body
103; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 1]
104; CHECK-NEXT:                 { Stmt_body[i0, i1] -> MemRef_phi[] };
105; CHECK-NEXT:            new: { Stmt_body[i0, i1] -> MemRef_A[i0] };
106; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
107; CHECK-NEXT:                 { Stmt_body[i0, i1] -> MemRef_join__phi[] };
108; CHECK-NEXT:     Stmt_body_true
109; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 1]
110; CHECK-NEXT:                 { Stmt_body_true[i0, i1] -> MemRef_phi[] };
111; CHECK-NEXT:            new: { Stmt_body_true[i0, i1] -> MemRef_A[i0] : i1 <= 1; Stmt_body_true[i0, 3] -> MemRef_A[i0] };
112; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
113; CHECK-NEXT:                 { Stmt_body_true[i0, i1] -> MemRef_A[i0] };
114; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
115; CHECK-NEXT:                 { Stmt_body_true[i0, i1] -> MemRef_join__phi[] };
116; CHECK-NEXT:     Stmt_body_join
117; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
118; CHECK-NEXT:                 { Stmt_body_join[i0, i1] -> MemRef_join[] };
119; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 1]
120; CHECK-NEXT:                 { Stmt_body_join[i0, i1] -> MemRef_join__phi[] };
121; CHECK-NEXT:     Stmt_reduction_inc
122; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 1]
123; CHECK-NEXT:                 { Stmt_reduction_inc[i0, i1] -> MemRef_join[] };
124; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
125; CHECK-NEXT:                 { Stmt_reduction_inc[i0, i1] -> MemRef_phi__phi[] };
126; CHECK-NEXT:            new: { Stmt_reduction_inc[i0, i1] -> MemRef_A[i0] : i1 <= 2 };
127; CHECK-NEXT: }
128