1; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s 2; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s 3 4 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" 6target triple = "x86_64-unknown-linux-gnu" 7 8define void @base_pointer_in_condition(i64** noalias %A_ptr, i64 %N) nounwind { 9entry: 10 fence seq_cst 11 br label %pre 12 13pre: 14 %A = load i64** %A_ptr 15 br i1 true, label %for.i, label %then 16 17for.i: 18 %indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ] 19 %scevgep = getelementptr i64* %A, i64 %indvar 20 store i64 %indvar, i64* %scevgep 21 %indvar.next = add nsw i64 %indvar, 1 22 %exitcond = icmp eq i64 %indvar.next, %N 23 br i1 %exitcond, label %then, label %for.i 24 25then: 26 br label %return 27 28return: 29 fence seq_cst 30 ret void 31} 32 33; CHECK-LABEL: base_pointer_in_condition 34; CHECK: Valid Region for Scop: for.i => then 35 36define void @base_pointer_is_argument(float* %A, i64 %n) { 37entry: 38 br label %for.i 39 40for.i: 41 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 42 br label %S1 43 44S1: 45 %conv = sitofp i64 %indvar.i to float 46 %arrayidx5 = getelementptr float* %A, i64 %indvar.i 47 store float %conv, float* %arrayidx5, align 4 48 br label %for.i.inc 49 50for.i.inc: 51 %indvar.i.next = add i64 %indvar.i, 1 52 %exitcond.i = icmp ne i64 %indvar.i.next, %n 53 br i1 %exitcond.i, label %for.i, label %exit 54 55exit: 56 ret void 57} 58 59; CHECK-LABEL: base_pointer_is_argument 60; CHECK: Valid Region for Scop: for.i => exit 61 62define void @base_pointer_is_const_expr(i64 %n) { 63entry: 64 br label %for.i 65 66for.i: 67 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 68 br label %S1 69 70S1: 71 %conv = sitofp i64 %indvar.i to float 72 %arrayidx5 = getelementptr float* inttoptr (i64 100 to float*), i64 %indvar.i 73 store float %conv, float* %arrayidx5, align 4 74 br label %for.i.inc 75 76for.i.inc: 77 %indvar.i.next = add i64 %indvar.i, 1 78 %exitcond.i = icmp ne i64 %indvar.i.next, %n 79 br i1 %exitcond.i, label %for.i, label %exit 80 81exit: 82 ret void 83} 84 85; CHECK-LABEL: base_pointer_is_const_expr 86; CHECK-LABEL: Valid Region for Scop: for.i => exit 87 88@A = external global float 89 90define void @base_pointer_is_global(i64 %n) { 91entry: 92 br label %for.i 93 94for.i: 95 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 96 br label %S1 97 98S1: 99 %conv = sitofp i64 %indvar.i to float 100 %arrayidx5 = getelementptr float* @A, i64 %indvar.i 101 store float %conv, float* %arrayidx5, align 4 102 br label %for.i.inc 103 104for.i.inc: 105 %indvar.i.next = add i64 %indvar.i, 1 106 %exitcond.i = icmp ne i64 %indvar.i.next, %n 107 br i1 %exitcond.i, label %for.i, label %exit 108 109exit: 110 ret void 111} 112 113; CHECK-LABEL: base_pointer_is_global 114; CHECK: Valid Region for Scop: for.i => exit 115 116declare float *@foo() 117 118define void @base_pointer_is_inst_outside(i64 %n) { 119entry: 120 %A = call float *@foo() 121 br label %for.i 122 123for.i: 124 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 125 br label %S1 126 127S1: 128 %conv = sitofp i64 %indvar.i to float 129 %arrayidx5 = getelementptr float* %A, i64 %indvar.i 130 store float %conv, float* %arrayidx5, align 4 131 br label %for.i.inc 132 133for.i.inc: 134 %indvar.i.next = add i64 %indvar.i, 1 135 %exitcond.i = icmp ne i64 %indvar.i.next, %n 136 br i1 %exitcond.i, label %for.i, label %exit 137 138exit: 139 ret void 140} 141 142; CHECK-LABEL: base_pointer_is_inst_outside 143; CHECK: Valid Region for Scop: for.i => exit 144 145declare float* @getNextBasePtr(float*) readnone nounwind 146 147define void @base_pointer_is_phi_node(i64 %n, float* %A) { 148entry: 149 br label %for.i 150 151for.i: 152 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 153 %ptr = phi float* [ %ptr.next, %for.i.inc ], [ %A, %entry ] 154; To get a PHI node inside a SCoP that can not be analyzed but 155; for which the surrounding SCoP is normally still valid we use a function 156; without any side effects. 157 %ptr.next = call float* @getNextBasePtr(float* %ptr) 158 br label %S1 159 160S1: 161 %conv = sitofp i64 %indvar.i to float 162 %arrayidx5 = getelementptr float* %ptr, i64 %indvar.i 163 store float %conv, float* %arrayidx5, align 4 164 br label %for.i.inc 165 166for.i.inc: 167 %indvar.i.next = add i64 %indvar.i, 1 168 %exitcond.i = icmp ne i64 %indvar.i.next, %n 169 br i1 %exitcond.i, label %for.i, label %exit 170 171exit: 172 ret void 173} 174 175; CHECK-LABEL: base_pointer_is_phi_node 176; CHECK-NOT: Valid Region for Scop 177 178define void @base_pointer_is_inst_inside_invariant_1(i64 %n, float* %A) { 179entry: 180 br label %for.i 181 182for.i: 183 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 184; To get an instruction inside a region, we use a function without side 185; effects on which SCEV blocks, but for which it is still clear that the 186; return value remains invariant throughout the whole loop. 187 %ptr = call float* @getNextBasePtr(float* %A) 188 br label %S1 189 190S1: 191 %conv = sitofp i64 %indvar.i to float 192 %arrayidx5 = getelementptr float* %ptr, i64 %indvar.i 193 store float %conv, float* %arrayidx5, align 4 194 br label %for.i.inc 195 196for.i.inc: 197 %indvar.i.next = add i64 %indvar.i, 1 198 %exitcond.i = icmp ne i64 %indvar.i.next, %n 199 br i1 %exitcond.i, label %for.i, label %exit 200 201exit: 202 ret void 203} 204 205; CHECK-LABEL: base_pointer_is_inst_inside_invariant_1 206; CHECK: Valid Region for Scop: for.i => exit 207 208declare float* @getNextBasePtr2(float*) readnone nounwind 209 210define void @base_pointer_is_inst_inside_invariant_2(i64 %n, float* %A) { 211entry: 212 br label %for.i 213 214for.i: 215 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 216 %ptr = call float* @getNextBasePtr2(float* %A) 217 %ptr2 = call float* @getNextBasePtr(float* %ptr) 218 br label %S1 219 220S1: 221 %conv = sitofp i64 %indvar.i to float 222 %arrayidx5 = getelementptr float* %ptr2, i64 %indvar.i 223 store float %conv, float* %arrayidx5, align 4 224 br label %for.i.inc 225 226for.i.inc: 227 %indvar.i.next = add i64 %indvar.i, 1 228 %exitcond.i = icmp ne i64 %indvar.i.next, %n 229 br i1 %exitcond.i, label %for.i, label %exit 230 231exit: 232 ret void 233} 234 235; CHECK-LABEL: base_pointer_is_inst_inside_invariant_2 236; CHECK: Valid Region for Scop: for.i => exit 237 238declare float* @getNextBasePtr3(float*, i64) readnone nounwind 239 240define void @base_pointer_is_inst_inside_variant(i64 %n, float* %A) { 241entry: 242 br label %for.i 243 244for.i: 245 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 246 %ptr = call float* @getNextBasePtr3(float* %A, i64 %indvar.i) 247 %ptr2 = call float* @getNextBasePtr(float* %ptr) 248 br label %S1 249 250S1: 251 %conv = sitofp i64 %indvar.i to float 252 %arrayidx5 = getelementptr float* %ptr2, i64 %indvar.i 253 store float %conv, float* %arrayidx5, align 4 254 br label %for.i.inc 255 256for.i.inc: 257 %indvar.i.next = add i64 %indvar.i, 1 258 %exitcond.i = icmp ne i64 %indvar.i.next, %n 259 br i1 %exitcond.i, label %for.i, label %exit 260 261exit: 262 ret void 263} 264 265; CHECK: base_pointer_is_inst_inside_variant 266; CHECK-NOT: Valid Region for Scop 267 268define void @base_pointer_is_ptr2ptr(float** noalias %A, i64 %n) { 269entry: 270 br label %for.i 271 272for.i: 273 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 274 %arrayidx = getelementptr float** %A, i64 %indvar.i 275 br label %for.j 276 277for.j: 278 %indvar.j = phi i64 [ 0, %for.i ], [ %indvar.j.next, %for.j ] 279 %conv = sitofp i64 %indvar.i to float 280 %basepointer = load float** %arrayidx, align 8 281 %arrayidx5 = getelementptr float* %basepointer, i64 %indvar.j 282 store float %conv, float* %arrayidx5, align 4 283 %indvar.j.next = add i64 %indvar.j, 1 284 %exitcond.j = icmp ne i64 %indvar.j.next, %n 285 br i1 %exitcond.j, label %for.j, label %for.i.inc 286 287for.i.inc: 288 %indvar.i.next = add i64 %indvar.i, 1 289 %exitcond.i = icmp ne i64 %indvar.i.next, %n 290 br i1 %exitcond.i, label %for.i, label %exit 291 292exit: 293 ret void 294} 295 296; CHECK: base_pointer_is_ptr2ptr 297; CHECK-NOT: Valid Region for Scop 298