1; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=print<polly-optree>' -disable-output < %s | FileCheck %s -match-full-lines 2; 3; Forward a the LoadInst %val into %bodyB. %val is executed multiple times, 4; we must get the last loaded values. 5; 6; for (int j = 0; j < n; j += 1) { 7; double val; 8; for (int i = 0; i < n; i += 1) { 9; bodyA: 10; val = B[j]; 11; } 12; 13; bodyB: 14; A[j] = val; 15; } 16; 17define void @func(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B) { 18entry: 19 br label %for 20 21for: 22 %j = phi i32 [0, %entry], [%j.inc, %inc] 23 %j.cmp = icmp sle i32 %j, %n 24 br i1 %j.cmp, label %bodyA, label %exit 25 26 bodyA: 27 %i = phi i32 [0, %for], [%i.inc, %bodyA] 28 %B_idx = getelementptr inbounds double, ptr %B, i32 %i 29 %val = load double, ptr %B_idx 30 %i.inc = add nuw nsw i32 %i, 1 31 %i.cmp = icmp slt i32 %i, %n 32 br i1 %i.cmp, label %bodyA, label %bodyB 33 34 bodyB: 35 %A_idx = getelementptr inbounds double, ptr %A, i32 %j 36 store double %val, ptr %A_idx 37 br label %inc 38 39inc: 40 %j.inc = add nuw nsw i32 %j, 1 41 br label %for 42 43exit: 44 br label %return 45 46return: 47 ret void 48} 49 50 51; CHECK: Statistics { 52; CHECK: Known loads forwarded: 1 53; CHECK: Operand trees forwarded: 1 54; CHECK: Statements with forwarded operand trees: 1 55; CHECK: } 56 57; CHECK: After statements { 58; CHECK-NEXT: Stmt_bodyA 59; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 60; CHECK-NEXT: [n] -> { Stmt_bodyA[i0, i1] -> MemRef_B[i1] }; 61; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] 62; CHECK-NEXT: [n] -> { Stmt_bodyA[i0, i1] -> MemRef_val[] }; 63; CHECK-NEXT: Instructions { 64; CHECK-NEXT: %val = load double, ptr %B_idx, align 8 65; CHECK-NEXT: %i.cmp = icmp slt i32 %i, %n 66; CHECK-NEXT: } 67; CHECK-NEXT: Stmt_bodyB 68; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 69; CHECK-NEXT: ; 70; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[n] }; 71; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 72; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] }; 73; CHECK-NEXT: Instructions { 74; CHECK-NEXT: %val = load double, ptr %B_idx, align 8 75; CHECK-NEXT: store double %val, ptr %A_idx, align 8 76; CHECK-NEXT: } 77; CHECK-NEXT: } 78