1; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s 2 3%s1 = type { [32000 x double], [32000 x double], [32000 x double] } 4 5define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) { 6; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks 7; CHECK-NEXT: loop.header: 8; CHECK-NEXT: Report: cannot identify array bounds 9; 10entry: 11 br label %loop.header 12 13loop.header: ; preds = %loop.latch, %entry 14 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 15 %iv.next = add nuw nsw i64 %iv, 1 16 %cmp5 = icmp ult i64 %iv, 15999 17 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 18 br i1 %cmp5, label %if.then, label %if.else 19 20if.then: ; preds = %loop.header 21 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 22 br label %loop.latch 23 24if.else: ; preds = %loop.header 25 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 26 br label %loop.latch 27 28loop.latch: ; preds = %if.else, %if.then 29 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 30 %v8 = load double, double* %gep.2.sink, align 8 31 %mul16 = fmul double 3.0, %v8 32 store double %mul16, double* %arrayidx, align 8 33 %exitcond.not = icmp eq i64 %iv.next, 32000 34 br i1 %exitcond.not, label %exit, label %loop.header 35 36exit: ; preds = %loop.latch 37 ret i32 10 38} 39 40define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) { 41; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks' 42; CHECK-NEXT: loop.header: 43; CHECK-NEXT: Report: cannot identify array bounds 44; 45entry: 46 br label %loop.header 47 48loop.header: ; preds = %loop.latch, %entry 49 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 50 %iv.next = add nuw nsw i64 %iv, 1 51 %cmp5 = icmp ult i64 %iv, 15999 52 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 53 br i1 %cmp5, label %if.then, label %if.else 54 55if.then: ; preds = %loop.header 56 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 57 br label %loop.latch 58 59if.else: ; preds = %loop.header 60 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 61 br label %loop.latch 62 63loop.latch: ; preds = %if.else, %if.then 64 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 65 %v8 = load double, double* %arrayidx, align 8 66 %mul16 = fmul double 3.0, %v8 67 store double %mul16, double* %gep.2.sink, align 8 68 %exitcond.not = icmp eq i64 %iv.next, 32000 69 br i1 %exitcond.not, label %exit, label %loop.header 70 71exit: ; preds = %loop.latch 72 ret i32 10 73} 74 75define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) { 76; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks' 77; CHECK-NEXT: loop.header: 78; CHECK-NEXT: Report: cannot identify array bounds 79; 80entry: 81 br label %loop.header 82 83loop.header: ; preds = %loop.latch, %entry 84 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 85 %iv.next = add nuw nsw i64 %iv, 1 86 %cmp5 = icmp ult i64 %iv, 15999 87 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 88 br i1 %cmp5, label %if.then, label %if.else 89 90if.then: ; preds = %loop.header 91 %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 92 br label %loop.latch 93 94if.else: ; preds = %loop.header 95 %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 96 br label %loop.latch 97 98loop.latch: ; preds = %if.else, %if.then 99 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 100 %v8 = load double, double* %arrayidx, align 8 101 %mul16 = fmul double 3.0, %v8 102 store double %mul16, double* %gep.2.sink, align 8 103 %exitcond.not = icmp eq i64 %iv.next, 32000 104 br i1 %exitcond.not, label %exit, label %loop.header 105 106exit: ; preds = %loop.latch 107 ret i32 10 108} 109 110define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 111; CHECK-LABEL: 'load_with_pointer_phi_outside_loop' 112; CHECK-NEXT: loop.header: 113; CHECK-NEXT: Report: unsafe dependent memory operations in loop 114; CHECK-NEXT: Dependences: 115; CHECK-NEXT: Unknown: 116; CHECK-NEXT: %v8 = load double, double* %ptr, align 8 -> 117; CHECK-NEXT: store double %mul16, double* %arrayidx, align 8 118; 119entry: 120 br i1 %c.0, label %if.then, label %if.else 121 122if.then: 123 br label %loop.ph 124 125if.else: 126 %ptr.select = select i1 %c.1, double* %C, double* %B 127 br label %loop.ph 128 129loop.ph: 130 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 131 br label %loop.header 132 133loop.header: ; preds = %loop.latch, %entry 134 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 135 %iv.next = add nuw nsw i64 %iv, 1 136 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 137 %v8 = load double, double* %ptr, align 8 138 %mul16 = fmul double 3.0, %v8 139 store double %mul16, double* %arrayidx, align 8 140 %exitcond.not = icmp eq i64 %iv.next, 32000 141 br i1 %exitcond.not, label %exit, label %loop.header 142 143exit: ; preds = %loop.latch 144 ret i32 10 145} 146 147define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 148; CHECK-LABEL: 'store_with_pointer_phi_outside_loop' 149; CHECK-NEXT: loop.header: 150; CHECK-NEXT: Report: unsafe dependent memory operations in loop. 151; CHECK-NEXT: Dependences: 152; CHECK-NEXT: Unknown: 153; CHECK-NEXT: %v8 = load double, double* %arrayidx, align 8 -> 154; CHECK-NEXT: store double %mul16, double* %ptr, align 8 155; 156entry: 157 br i1 %c.0, label %if.then, label %if.else 158 159if.then: 160 br label %loop.ph 161 162if.else: 163 %ptr.select = select i1 %c.1, double* %C, double* %B 164 br label %loop.ph 165 166loop.ph: 167 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 168 br label %loop.header 169 170loop.header: ; preds = %loop.latch, %entry 171 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 172 %iv.next = add nuw nsw i64 %iv, 1 173 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 174 %v8 = load double, double* %arrayidx, align 8 175 %mul16 = fmul double 3.0, %v8 176 store double %mul16, double* %ptr, align 8 177 %exitcond.not = icmp eq i64 %iv.next, 32000 178 br i1 %exitcond.not, label %exit, label %loop.header 179 180exit: ; preds = %loop.latch 181 ret i32 10 182} 183 184define i32 @store_with_pointer_phi_incoming_phi(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 185; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi' 186; CHECK-NEXT: loop.header: 187; CHECK-NEXT: Report: cannot identify array bounds 188; CHECK-NEXT: Dependences: 189; CHECK-NEXT: Run-time memory checks: 190; CHECK-NEXT: Grouped accesses: 191; CHECK-EMPTY 192entry: 193 br label %loop.header 194 195loop.header: ; preds = %loop.latch, %entry 196 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 197 %iv.next = add nuw nsw i64 %iv, 1 198 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 199 %v8 = load double, double* %arrayidx, align 8 200 %mul16 = fmul double 3.0, %v8 201 br i1 %c.0, label %loop.then, label %loop.latch 202 203loop.then: 204 br i1 %c.0, label %loop.then.2, label %loop.else.2 205 206loop.then.2: 207 br label %merge.2 208 209loop.else.2: 210 br label %merge.2 211 212 213merge.2: 214 %ptr = phi double* [ %A, %loop.then.2 ], [ %B, %loop.else.2 ] 215 br label %loop.latch 216 217 218loop.latch: 219 %ptr.2 = phi double* [ %ptr, %merge.2], [ %C, %loop.header ] 220 store double %mul16, double* %ptr.2, align 8 221 %exitcond.not = icmp eq i64 %iv.next, 32000 222 br i1 %exitcond.not, label %exit, label %loop.header 223 224exit: ; preds = %loop.latch 225 ret i32 10 226} 227 228; Test cases with pointer phis forming a cycle. 229define i32 @store_with_pointer_phi_incoming_phi_irreducible_cycle(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 230; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi_irreducible_cycle' 231; CHECK-NEXT: loop.header: 232; CHECK-NEXT: Report: cannot identify array bounds 233; CHECK-NEXT: Dependences: 234; CHECK-NEXT: Run-time memory checks: 235; CHECK-NEXT: Grouped accesses: 236; CHECK-EMPTY 237entry: 238 br label %loop.header 239 240loop.header: ; preds = %loop.latch, %entry 241 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 242 %iv.next = add nuw nsw i64 %iv, 1 243 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 244 %v8 = load double, double* %arrayidx, align 8 245 %mul16 = fmul double 3.0, %v8 246 br i1 %c.0, label %loop.then, label %loop.latch 247 248loop.then: 249 br i1 %c.0, label %BB.A, label %BB.B 250 251BB.A: 252 %ptr = phi double* [ %A, %loop.then ], [ %ptr.2, %BB.B ] 253 br label %BB.B 254 255BB.B: 256 %ptr.2 = phi double* [ %ptr, %BB.A ], [ %B, %loop.then ] 257 br i1 %c.1, label %loop.latch, label %BB.A 258 259loop.latch: 260 %ptr.3 = phi double* [ %ptr.2, %BB.B ], [ %C, %loop.header ] 261 store double %mul16, double* %ptr.3, align 8 262 %exitcond.not = icmp eq i64 %iv.next, 32000 263 br i1 %exitcond.not, label %exit, label %loop.header 264 265exit: ; preds = %loop.latch 266 ret i32 10 267} 268 269define i32 @store_with_pointer_phi_outside_loop_select(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 270; CHECK-LABEL: 'store_with_pointer_phi_outside_loop_select' 271; CHECK-NEXT: loop.header: 272; CHECK-NEXT: Report: unsafe dependent memory operations in loop. 273; CHECK-NEXT: Dependences: 274; CHECK-NEXT: Unknown: 275; CHECK-NEXT: %v8 = load double, double* %arrayidx, align 8 -> 276; CHECK-NEXT: store double %mul16, double* %ptr, align 8 277; 278entry: 279 br i1 %c.0, label %if.then, label %if.else 280 281if.then: 282 br label %loop.ph 283 284if.else: 285 %ptr.select = select i1 %c.1, double* %C, double* %B 286 br label %loop.ph 287 288loop.ph: 289 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 290 br label %loop.header 291 292loop.header: ; preds = %loop.latch, %entry 293 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 294 %iv.next = add nuw nsw i64 %iv, 1 295 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 296 %v8 = load double, double* %arrayidx, align 8 297 %mul16 = fmul double 3.0, %v8 298 store double %mul16, double* %ptr, align 8 299 %exitcond.not = icmp eq i64 %iv.next, 32000 300 br i1 %exitcond.not, label %exit, label %loop.header 301 302exit: ; preds = %loop.latch 303 ret i32 10 304} 305 306define i32 @store_with_pointer_phi_in_same_bb_use_other_phi(double* %A, double* %B, double* %C, double* %D, i1 %c.0, i1 %c.1) { 307; CHECK-LABEL: Loop access info in function 'store_with_pointer_phi_in_same_bb_use_other_phi': 308; CHECK-NEXT: loop.header: 309; CHECK-NEXT: Report: cannot identify array bounds 310; CHECK-NEXT: Dependences: 311; CHECK-NEXT: Run-time memory checks: 312; CHECK-NEXT: Grouped accesses: 313; CHECK-EMPTY: 314; 315entry: 316 br label %loop.header 317 318loop.header: ; preds = %loop.latch, %entry 319 %ptr.0 = phi double* [ %C, %entry ], [ %D, %loop.header ] 320 %ptr.1 = phi double* [ %B, %entry ], [ %ptr.0, %loop.header ] 321 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.header ] 322 %iv.next = add nuw nsw i64 %iv, 1 323 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 324 %v8 = load double, double* %arrayidx, align 8 325 %mul16 = fmul double 3.0, %v8 326 store double %mul16, double* %ptr.1, align 8 327 %exitcond.not = icmp eq i64 %iv.next, 32000 328 br i1 %exitcond.not, label %exit, label %loop.header 329 330exit: ; preds = %loop.latch 331 ret i32 10 332} 333 334define void @phi_load_store_memdep_check(i1 %c, i16* %A, i16* %B, i16* %C) { 335; CHECK-LABEL: Loop access info in function 'phi_load_store_memdep_check': 336; CHECK-NEXT: for.body: 337; CHECK-NEXT: Report: cannot identify array bounds 338; CHECK-NEXT: Dependences: 339; CHECK-NEXT: Run-time memory checks: 340; CHECK-NEXT: Grouped accesses: 341; CHECK-EMPTY: 342; 343entry: 344 br label %for.body 345 346for.body: ; preds = %if.end, %entry 347 %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ] 348 %lv = load i16, i16* %A, align 1 349 store i16 %lv, i16* %A, align 1 350 br i1 %c, label %if.then, label %if.end 351 352if.then: ; preds = %for.body 353 %lv2 = load i16, i16* %A, align 1 354 br label %if.end 355 356if.end: ; preds = %if.then, %for.body 357 %c.sink = phi i16* [ %B, %if.then ], [ %C, %for.body ] 358 %lv3 = load i16, i16* %c.sink 359 %add = add i16 %lv3, 10 360 store i16 %add, i16* %c.sink, align 1 361 %iv.next = add nuw nsw i16 %iv, 1 362 %tobool.not = icmp eq i16 %iv.next, 1000 363 br i1 %tobool.not, label %for.end.loopexit, label %for.body 364 365for.end.loopexit: ; preds = %if.end 366 ret void 367} 368