1; RUN: opt %loadPolly -polly-scops -analyze < %s \ 2; RUN: -polly-invariant-load-hoisting \ 3; RUN: | FileCheck %s 4 5; Verify that nested arrays with invariant base pointers are handled correctly. 6; Specifically, we currently do not canonicalize arrays where some accesses are 7; hoisted as invariant loads. If we would, we need to update the access function 8; of the invariant loads as well. However, as this is not a very common 9; situation, we leave this for now to avoid further complexity increases. 10; 11; In this test case the arrays baseA1 and baseA2 could be canonicalized to a 12; single array, but there is also an invariant access to baseA1[0] through 13; "%v0 = load float, float* %ptr" which prevents the canonicalization. 14 15; CHECK: Invariant Accesses: { 16; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 17; CHECK-NEXT: { Stmt_body2[i0] -> MemRef_A[0] }; 18; CHECK-NEXT: Execution Context: { : } 19; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 20; CHECK-NEXT: { Stmt_body1[i0] -> MemRef_baseA1[0] }; 21; CHECK-NEXT: Execution Context: { : } 22; CHECK-NEXT: } 23 24; CHECK: Statements { 25; CHECK-NEXT: Stmt_body1 26; CHECK-NEXT: Domain := 27; CHECK-NEXT: { Stmt_body1[i0] : 0 <= i0 <= 1021 }; 28; CHECK-NEXT: Schedule := 29; CHECK-NEXT: { Stmt_body1[i0] -> [i0, 0] }; 30; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 31; CHECK-NEXT: { Stmt_body1[i0] -> MemRef_baseA1[1 + i0] }; 32; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 33; CHECK-NEXT: { Stmt_body1[i0] -> MemRef_B[0] }; 34; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 35; CHECK-NEXT: { Stmt_body1[i0] -> MemRef_B[0] }; 36; CHECK-NEXT: Stmt_body2 37; CHECK-NEXT: Domain := 38; CHECK-NEXT: { Stmt_body2[i0] : 0 <= i0 <= 1021 }; 39; CHECK-NEXT: Schedule := 40; CHECK-NEXT: { Stmt_body2[i0] -> [i0, 1] }; 41; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 42; CHECK-NEXT: { Stmt_body2[i0] -> MemRef_baseA2[0] }; 43; CHECK-NEXT: } 44 45define void @foo(float** %A, float* %B) { 46start: 47 br label %loop 48 49loop: 50 %indvar = phi i64 [1, %start], [%indvar.next, %latch] 51 %indvar.next = add nsw i64 %indvar, 1 52 %icmp = icmp slt i64 %indvar.next, 1024 53 br i1 %icmp, label %body1, label %exit 54 55body1: 56 %baseA1 = load float*, float** %A 57 %ptr = getelementptr inbounds float, float* %baseA1, i64 %indvar 58 %v0 = load float, float* %ptr 59 %v1 = load float, float* %baseA1 60 store float %v0, float* %B 61 store float %v1, float* %B 62 br label %body2 63 64body2: 65 %baseA2 = load float*, float** %A 66 store float undef, float* %baseA2 67 br label %body3 68 69body3: 70 br label %latch 71 72latch: 73 br label %loop 74 75exit: 76 ret void 77 78} 79