xref: /llvm-project/polly/test/ForwardOpTree/forward_load_differentarray.ll (revision e1f056f692d869708c1898d9d65a69ac5584a0ed)
1; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=print<polly-optree>' -disable-output < %s | FileCheck %s -match-full-lines
2;
3; To forward %val, B[j] cannot be reused in bodyC because it is overwritten
4; between. Verify that instead the alternative C[j] is used.
5;
6; for (int j = 0; j < n; j += 1) {
7; bodyA:
8;   double val = B[j];
9;
10; bodyB:
11;   B[j] = 0;
12;   C[j] = val;
13;
14; bodyC:
15;   A[j] = val;
16; }
17;
18define void @func(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B, ptr noalias nonnull %C) {
19entry:
20  br label %for
21
22for:
23  %j = phi i32 [0, %entry], [%j.inc, %inc]
24  %j.cmp = icmp slt i32 %j, %n
25  br i1 %j.cmp, label %bodyA, label %exit
26
27    bodyA:
28      %B_idx = getelementptr inbounds double, ptr %B, i32 %j
29      %val = load double, ptr %B_idx
30      br label %bodyB
31
32    bodyB:
33      store double 0.0, ptr %B_idx
34      %C_idx = getelementptr inbounds double, ptr %C, i32 %j
35      store double %val, ptr %C_idx
36      br label %bodyC
37
38    bodyC:
39      %A_idx = getelementptr inbounds double, ptr %A, i32 %j
40      store double %val, ptr %A_idx
41      br label %inc
42
43inc:
44  %j.inc = add nuw nsw i32 %j, 1
45  br label %for
46
47exit:
48  br label %return
49
50return:
51  ret void
52}
53
54
55; CHECK: Statistics {
56; CHECK:     Known loads forwarded: 2
57; CHECK:     Operand trees forwarded: 2
58; CHECK:     Statements with forwarded operand trees: 2
59; CHECK: }
60
61; CHECK-NEXT: After statements {
62; CHECK-NEXT:     Stmt_bodyA
63; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
64; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_B[i0] };
65; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
66; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
67; CHECK-NEXT:             Instructions {
68; CHECK-NEXT:                   %val = load double, ptr %B_idx, align 8
69; CHECK-NEXT:             }
70; CHECK-NEXT:     Stmt_bodyB
71; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
72; CHECK-NEXT:                 ;
73; CHECK-NEXT:            new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
74; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
75; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
76; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
77; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
78; CHECK-NEXT:             Instructions {
79; CHECK-NEXT:                   %val = load double, ptr %B_idx, align 8
80; CHECK-NEXT:                   store double 0.000000e+00, ptr %B_idx, align 8
81; CHECK-NEXT:                   store double %val, ptr %C_idx, align 8
82; CHECK-NEXT:             }
83; CHECK-NEXT:     Stmt_bodyC
84; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
85; CHECK-NEXT:                 ;
86; CHECK-NEXT:            new: [n] -> { Stmt_bodyC[i0] -> MemRef_C[i0] };
87; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
88; CHECK-NEXT:                 [n] -> { Stmt_bodyC[i0] -> MemRef_A[i0] };
89; CHECK-NEXT:             Instructions {
90; CHECK-NEXT:                   %val = load double, ptr %B_idx, align 8
91; CHECK-NEXT:                   store double %val, ptr %A_idx, align 8
92; CHECK-NEXT:             }
93; CHECK-NEXT: }
94