1; RUN: opt %loadPolly -disable-basic-aa -polly-invariant-load-hoisting=true -polly-print-detect -disable-output < %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(ptr noalias %A_ptr, i64 %N) nounwind { 7entry: 8 fence seq_cst 9 br label %pre 10 11pre: 12 %A = load ptr, ptr %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, ptr %A, i64 %indvar 18 store i64 %indvar, ptr %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(ptr %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, ptr %A, i64 %indvar.i 45 store float %conv, ptr %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, ptr inttoptr (i64 100 to ptr), i64 %indvar.i 71 store float %conv, ptr %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, ptr @A, i64 %indvar.i 99 store float %conv, ptr %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 ptr @foo() 115 116define void @base_pointer_is_inst_outside(i64 %n) { 117entry: 118 %A = call ptr @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, ptr %A, i64 %indvar.i 128 store float %conv, ptr %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 ptr @getNextBasePtr(ptr) readnone nounwind 144 145define void @base_pointer_is_phi_node(i64 %n, ptr %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 ptr [ %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 ptr @getNextBasePtr(ptr %ptr) 156 br label %S1 157 158S1: 159 %conv = sitofp i64 %indvar.i to float 160 %arrayidx5 = getelementptr float, ptr %ptr, i64 %indvar.i 161 store float %conv, ptr %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, ptr %A) { 177entry: 178 br label %for.i 179 180for.i: 181 %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] 182; A function return value, even with readnone nounwind attributes, is not 183; considered a valid base pointer because it can return a pointer that aliases 184; with something else (e.g. %A or a global) or return a different pointer at 185; every call (e.g. malloc) 186 %ptr = call ptr @getNextBasePtr(ptr %A) 187 br label %S1 188 189S1: 190 %conv = sitofp i64 %indvar.i to float 191 %arrayidx5 = getelementptr float, ptr %ptr, i64 %indvar.i 192 store float %conv, ptr %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-NOT: Valid Region for Scop 206 207declare ptr @getNextBasePtr2(ptr) readnone nounwind 208 209define void @base_pointer_is_inst_inside_invariant_2(i64 %n, ptr %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 ptr @getNextBasePtr2(ptr %A) 216 %ptr2 = call ptr @getNextBasePtr(ptr %ptr) 217 br label %S1 218 219S1: 220 %conv = sitofp i64 %indvar.i to float 221 %arrayidx5 = getelementptr float, ptr %ptr2, i64 %indvar.i 222 store float %conv, ptr %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-NOT: Valid Region for Scop 236 237declare ptr @getNextBasePtr3(ptr, i64) readnone nounwind 238 239define void @base_pointer_is_inst_inside_variant(i64 %n, ptr %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 ptr @getNextBasePtr3(ptr %A, i64 %indvar.i) 246 %ptr2 = call ptr @getNextBasePtr(ptr %ptr) 247 br label %S1 248 249S1: 250 %conv = sitofp i64 %indvar.i to float 251 %arrayidx5 = getelementptr float, ptr %ptr2, i64 %indvar.i 252 store float %conv, ptr %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(ptr 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 ptr, ptr %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 ptr, ptr %arrayidx, align 8 280 %arrayidx5 = getelementptr float, ptr %basepointer, i64 %indvar.j 281 store float %conv, ptr %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: Valid Region for Scop: for.j => for.i.inc 297