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