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