170af4f57SMichael Kruse; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
270af4f57SMichael Kruse;
3*235726eeSMichael Kruse; To forward %val, B[j] cannot be reused in bodyC because it is overwritten
4*235726eeSMichael Kruse; between. Verify that instead the alternative C[j] is used.
5*235726eeSMichael Kruse;
6*235726eeSMichael Kruse; for (int j = 0; j < n; j += 1) {
7*235726eeSMichael Kruse; bodyA:
8*235726eeSMichael Kruse;   double val = B[j];
9*235726eeSMichael Kruse;
10*235726eeSMichael Kruse; bodyB:
11*235726eeSMichael Kruse;   B[j] = 0;
12*235726eeSMichael Kruse;   C[j] = val;
13*235726eeSMichael Kruse;
14*235726eeSMichael Kruse; bodyC:
15*235726eeSMichael Kruse;   A[j] = val;
16*235726eeSMichael Kruse; }
17*235726eeSMichael Kruse;
1870af4f57SMichael Krusedefine void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B, double* noalias nonnull %C) {
1970af4f57SMichael Kruseentry:
2070af4f57SMichael Kruse  br label %for
2170af4f57SMichael Kruse
2270af4f57SMichael Krusefor:
2370af4f57SMichael Kruse  %j = phi i32 [0, %entry], [%j.inc, %inc]
2470af4f57SMichael Kruse  %j.cmp = icmp slt i32 %j, %n
2570af4f57SMichael Kruse  br i1 %j.cmp, label %bodyA, label %exit
2670af4f57SMichael Kruse
2770af4f57SMichael Kruse    bodyA:
2870af4f57SMichael Kruse      %B_idx = getelementptr inbounds double, double* %B, i32 %j
2970af4f57SMichael Kruse      %val = load double, double* %B_idx
3070af4f57SMichael Kruse      br label %bodyB
3170af4f57SMichael Kruse
3270af4f57SMichael Kruse    bodyB:
3370af4f57SMichael Kruse      store double 0.0, double* %B_idx
3470af4f57SMichael Kruse      %C_idx = getelementptr inbounds double, double* %C, i32 %j
3570af4f57SMichael Kruse      store double %val, double* %C_idx
3670af4f57SMichael Kruse      br label %bodyC
3770af4f57SMichael Kruse
3870af4f57SMichael Kruse    bodyC:
3970af4f57SMichael Kruse      %A_idx = getelementptr inbounds double, double* %A, i32 %j
4070af4f57SMichael Kruse      store double %val, double* %A_idx
4170af4f57SMichael Kruse      br label %inc
4270af4f57SMichael Kruse
4370af4f57SMichael Kruseinc:
4470af4f57SMichael Kruse  %j.inc = add nuw nsw i32 %j, 1
4570af4f57SMichael Kruse  br label %for
4670af4f57SMichael Kruse
4770af4f57SMichael Kruseexit:
4870af4f57SMichael Kruse  br label %return
4970af4f57SMichael Kruse
5070af4f57SMichael Krusereturn:
5170af4f57SMichael Kruse  ret void
5270af4f57SMichael Kruse}
5370af4f57SMichael Kruse
5470af4f57SMichael Kruse
5570af4f57SMichael Kruse; CHECK: Statistics {
5670af4f57SMichael Kruse; CHECK:     Known loads forwarded: 2
5770af4f57SMichael Kruse; CHECK:     Operand trees forwarded: 2
5870af4f57SMichael Kruse; CHECK:     Statements with forwarded operand trees: 2
5970af4f57SMichael Kruse; CHECK: }
6070af4f57SMichael Kruse
6170af4f57SMichael Kruse; CHECK-NEXT: After statements {
6270af4f57SMichael Kruse; CHECK-NEXT:     Stmt_bodyA
6370af4f57SMichael Kruse; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
6470af4f57SMichael Kruse; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_B[i0] };
6570af4f57SMichael Kruse; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
6670af4f57SMichael Kruse; CHECK-NEXT:                 [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
6770af4f57SMichael Kruse; CHECK-NEXT:             Instructions {
6870af4f57SMichael Kruse; CHECK-NEXT:                   %val = load double, double* %B_idx
6970af4f57SMichael Kruse; CHECK-NEXT:             }
7070af4f57SMichael Kruse; CHECK-NEXT:     Stmt_bodyB
7170af4f57SMichael Kruse; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
7270af4f57SMichael Kruse; CHECK-NEXT:                 null;
7370af4f57SMichael Kruse; CHECK-NEXT:            new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
7470af4f57SMichael Kruse; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
7570af4f57SMichael Kruse; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
7670af4f57SMichael Kruse; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
7770af4f57SMichael Kruse; CHECK-NEXT:                 [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
7870af4f57SMichael Kruse; CHECK-NEXT:             Instructions {
7970af4f57SMichael Kruse; CHECK-NEXT:                   %val = load double, double* %B_idx
8070af4f57SMichael Kruse; CHECK-NEXT:                   store double 0.000000e+00, double* %B_idx
8170af4f57SMichael Kruse; CHECK-NEXT:                   store double %val, double* %C_idx
8270af4f57SMichael Kruse; CHECK-NEXT:             }
8370af4f57SMichael Kruse; CHECK-NEXT:     Stmt_bodyC
8470af4f57SMichael Kruse; CHECK-NEXT:             ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
8570af4f57SMichael Kruse; CHECK-NEXT:                 null;
8670af4f57SMichael Kruse; CHECK-NEXT:            new: [n] -> { Stmt_bodyC[i0] -> MemRef_C[i0] };
8770af4f57SMichael Kruse; CHECK-NEXT:             MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
8870af4f57SMichael Kruse; CHECK-NEXT:                 [n] -> { Stmt_bodyC[i0] -> MemRef_A[i0] };
8970af4f57SMichael Kruse; CHECK-NEXT:             Instructions {
9070af4f57SMichael Kruse; CHECK-NEXT:                   %val = load double, double* %B_idx
9170af4f57SMichael Kruse; CHECK-NEXT:                   store double %val, double* %A_idx
9270af4f57SMichael Kruse; CHECK-NEXT:             }
9370af4f57SMichael Kruse; CHECK-NEXT: }
94