[Transforms] Silence a warning in SROA.cpp (NFC)
[llvm-project.git] / polly / test / ForwardOpTree / forward_load_tripleuse.ll
blob7526a8313945d5ebe27369b35eaa64e77f1a91ce
1 ; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=print<polly-optree>,polly-codegen' -disable-output < %s | FileCheck %s -match-full-lines
3 ; %val1 is used three times: Twice by its own operand tree of %val2 and once
4 ; more by the store in %bodyB.
5 ; Verify that we can handle multiple uses by the same instruction and uses
6 ; in multiple statements as well.
7 ; The result processing may depend on the order in which the values are used,
8 ; hence we check both orderings.
10 ; for (int j = 0; j < n; j += 1) {
11 ; bodyA:
12 ;   double val1 = A[j];
13 ;   double val2 = val1 + val1;
15 ; bodyB:
16 ;   B[j] = val1;
17 ;   C[j] = val2;
18 ; }
20 define void @func1(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B, ptr noalias nonnull %C) {
21 entry:
22   br label %for
24 for:
25   %j = phi i32 [0, %entry], [%j.inc, %inc]
26   %j.cmp = icmp slt i32 %j, %n
27   br i1 %j.cmp, label %bodyA, label %exit
29     bodyA:
30       %A_idx = getelementptr inbounds double, ptr %A, i32 %j
31       %val1 = load double, ptr %A_idx
32       %val2 = fadd double %val1, %val1
33       br label %bodyB
35     bodyB:
36       %B_idx = getelementptr inbounds double, ptr %B, i32 %j
37       store double %val1, ptr %B_idx
38       %C_idx = getelementptr inbounds double, ptr %C, i32 %j
39       store double %val2, ptr %C_idx
40       br label %inc
42 inc:
43   %j.inc = add nuw nsw i32 %j, 1
44   br label %for
46 exit:
47   br label %return
49 return:
50   ret void
54 ; CHECK: Statistics {
55 ; CHECK:     Instructions copied: 1
56 ; CHECK:     Known loads forwarded: 2
57 ; CHECK:     Operand trees forwarded: 2
58 ; CHECK:     Statements with forwarded operand trees: 1
59 ; CHECK: }
61 ; CHECK:      After statements {
62 ; CHECK-NEXT:     Stmt_bodyA
63 ; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
64 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };
65 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
66 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };
67 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
68 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };
69 ; CHECK-NEXT:             Instructions {
70 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
71 ; CHECK-NEXT:                   %val2 = fadd double %val1, %val1
72 ; CHECK-NEXT:             }
73 ; CHECK-NEXT:     Stmt_bodyB
74 ; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
75 ; CHECK-NEXT:                 ;
76 ; CHECK-NEXT:            new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
77 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
78 ; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
79 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
80 ; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
81 ; CHECK-NEXT:             Instructions {
82 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
83 ; CHECK-NEXT:                   %val2 = fadd double %val1, %val1
84 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
85 ; CHECK-NEXT:                   store double %val1, ptr %B_idx, align 8
86 ; CHECK-NEXT:                   store double %val2, ptr %C_idx, align 8
87 ; CHECK-NEXT:             }
88 ; CHECK-NEXT: }
91 define void @func2(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B, ptr noalias nonnull %C) {
92 entry:
93   br label %for
95 for:
96   %j = phi i32 [0, %entry], [%j.inc, %inc]
97   %j.cmp = icmp slt i32 %j, %n
98   br i1 %j.cmp, label %bodyA, label %exit
100     bodyA:
101       %A_idx = getelementptr inbounds double, ptr %A, i32 %j
102       %val1 = load double, ptr %A_idx
103       %val2 = fadd double %val1, %val1
104       br label %bodyB
106     bodyB:
107       %B_idx = getelementptr inbounds double, ptr %B, i32 %j
108       store double %val2, ptr %B_idx
109       %C_idx = getelementptr inbounds double, ptr %C, i32 %j
110       store double %val1, ptr %C_idx
111       br label %inc
113 inc:
114   %j.inc = add nuw nsw i32 %j, 1
115   br label %for
117 exit:
118   br label %return
120 return:
121   ret void
125 ; CHECK: Statistics {
126 ; CHECK:     Instructions copied: 1
127 ; CHECK:     Known loads forwarded: 2
128 ; CHECK:     Operand trees forwarded: 2
129 ; CHECK:     Statements with forwarded operand trees: 1
130 ; CHECK: }
132 ; CHECK:      After statements {
133 ; CHECK-NEXT:     Stmt_bodyA
134 ; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
135 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };
136 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
137 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };
138 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
139 ; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };
140 ; CHECK-NEXT:             Instructions {
141 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
142 ; CHECK-NEXT:                   %val2 = fadd double %val1, %val1
143 ; CHECK-NEXT:             }
144 ; CHECK-NEXT:     Stmt_bodyB
145 ; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
146 ; CHECK-NEXT:                 ;
147 ; CHECK-NEXT:            new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
148 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
149 ; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
150 ; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
151 ; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
152 ; CHECK-NEXT:             Instructions {
153 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
154 ; CHECK-NEXT:                   %val1 = load double, ptr %A_idx, align 8
155 ; CHECK-NEXT:                   %val2 = fadd double %val1, %val1
156 ; CHECK-NEXT:                   store double %val2, ptr %B_idx, align 8
157 ; CHECK-NEXT:                   store double %val1, ptr %C_idx, align 8
158 ; CHECK-NEXT:             }
159 ; CHECK-NEXT: }