1; RUN: opt %loadPolly -basic-aa -polly-scops -analyze < %s | FileCheck %s 2; RUN: opt %loadPolly -basic-aa -polly-function-scops -analyze < %s | FileCheck %s 3 4; ModuleID = 'scalar_to_array.ll' 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6 7@A = common global [1024 x float] zeroinitializer, align 8 8 9; Terminating loops without side-effects will be optimzied away, hence 10; detecting a scop would be pointless. 11; CHECK-NOT: Function: empty 12; Function Attrs: nounwind 13define i32 @empty() #0 { 14entry: 15 fence seq_cst 16 br label %for.cond 17 18for.cond: ; preds = %for.inc, %entry 19 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] 20 %exitcond = icmp ne i64 %indvar, 1024 21 br i1 %exitcond, label %for.body, label %return 22 23for.body: ; preds = %for.cond 24 br label %for.inc 25 26for.inc: ; preds = %for.body 27 %indvar.next = add i64 %indvar, 1 28 br label %for.cond 29 30return: ; preds = %for.cond 31 fence seq_cst 32 ret i32 0 33} 34 35; CHECK-LABEL: Function: array_access 36; Function Attrs: nounwind 37define i32 @array_access() #0 { 38entry: 39 fence seq_cst 40 br label %for.cond 41 42for.cond: ; preds = %for.inc, %entry 43 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] 44 %exitcond = icmp ne i64 %indvar, 1024 45 br i1 %exitcond, label %for.body, label %return 46 47for.body: ; preds = %for.cond 48 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar 49 %float = uitofp i64 %indvar to float 50 store float %float, float* %arrayidx 51 br label %for.inc 52; CHECK: Stmt_for_body 53; CHECK-NOT: ReadAccess 54; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 55; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] }; 56 57for.inc: ; preds = %for.body 58 %indvar.next = add i64 %indvar, 1 59 br label %for.cond 60 61return: ; preds = %for.cond 62 fence seq_cst 63 ret i32 0 64} 65 66; Function Attrs: nounwind 67; CHECK-LABEL: Function: intra_scop_dep 68define i32 @intra_scop_dep() #0 { 69entry: 70 fence seq_cst 71 br label %for.cond 72 73for.cond: ; preds = %for.inc, %entry 74 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] 75 %exitcond = icmp ne i64 %indvar, 1024 76 br i1 %exitcond, label %for.body.a, label %return 77 78for.body.a: ; preds = %for.cond 79 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar 80 %scalar = load float, float* %arrayidx 81 br label %for.body.b 82; CHECK: Stmt_for_body_a 83; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 84; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_A[i0] }; 85; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] 86; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_scalar[] }; 87 88for.body.b: ; preds = %for.body.a 89 %arrayidx2 = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar 90 %float = uitofp i64 %indvar to float 91 %sum = fadd float %scalar, %float 92 store float %sum, float* %arrayidx2 93 br label %for.inc 94; CHECK: Stmt_for_body_b 95; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] 96; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_scalar[] }; 97; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 98; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_A[i0] }; 99 100for.inc: ; preds = %for.body.b 101 %indvar.next = add i64 %indvar, 1 102 br label %for.cond 103 104return: ; preds = %for.cond 105 fence seq_cst 106 ret i32 0 107} 108 109; It is not possible to have a scop which accesses a scalar element that is 110; a global variable. All global variables are pointers containing possibly 111; a single element. Hence they do not need to be handled anyways. 112; Please note that this is still required when scalar to array rewritting is 113; disabled. 114 115; CHECK-LABEL: Function: use_after_scop 116; Function Attrs: nounwind 117define i32 @use_after_scop() #0 { 118entry: 119 %scalar.s2a = alloca float 120 fence seq_cst 121 br label %for.head 122 123for.head: ; preds = %for.inc, %entry 124 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] 125 br label %for.body 126 127for.body: ; preds = %for.head 128 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar 129 %scalar = load float, float* %arrayidx 130 store float %scalar, float* %scalar.s2a 131; Escaped uses are still required to be rewritten to stack variable. 132; CHECK: Stmt_for_body 133; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] 134; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] }; 135; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 136; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_scalar_s2a[0] }; 137 br label %for.inc 138 139for.inc: ; preds = %for.body 140 %indvar.next = add i64 %indvar, 1 141 %exitcond = icmp ne i64 %indvar.next, 1024 142 br i1 %exitcond, label %for.head, label %for.after 143 144for.after: ; preds = %for.inc 145 %scalar.loadoutside = load float, float* %scalar.s2a 146 fence seq_cst 147 %return_value = fptosi float %scalar.loadoutside to i32 148 br label %return 149 150return: ; preds = %for.after 151 ret i32 %return_value 152} 153 154; We currently do not transform scalar references, that have only read accesses 155; in the scop. There are two reasons for this: 156; 157; o We don't introduce additional memory references which may yield to compile 158; time overhead. 159; o For integer values, such a translation may block the use of scalar 160; evolution on those values. 161; 162; CHECK-LABEL: Function: before_scop 163; Function Attrs: nounwind 164define i32 @before_scop() #0 { 165entry: 166 br label %preheader 167 168preheader: ; preds = %entry 169 %scalar = fadd float 4.000000e+00, 5.000000e+00 170 fence seq_cst 171 br label %for.cond 172 173for.cond: ; preds = %for.inc, %preheader 174 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %preheader ] 175 %exitcond = icmp ne i64 %indvar, 1024 176 br i1 %exitcond, label %for.body, label %return 177 178for.body: ; preds = %for.cond 179 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar 180 store float %scalar, float* %arrayidx 181 br label %for.inc 182; CHECK: Stmt_for_body 183; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] 184; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] }; 185 186for.inc: ; preds = %for.body 187 %indvar.next = add i64 %indvar, 1 188 br label %for.cond 189 190return: ; preds = %for.cond 191 fence seq_cst 192 ret i32 0 193} 194 195attributes #0 = { nounwind } 196