1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s 3 4; Loop guard for %off guarantees the accesses in the loop do not overlap. 5define void @access_after_via_loop_guard(ptr %a, i64 %off) { 6; CHECK-LABEL: 'access_after_via_loop_guard' 7; CHECK-NEXT: loop: 8; CHECK-NEXT: Memory dependences are safe 9; CHECK-NEXT: Dependences: 10; CHECK-NEXT: Run-time memory checks: 11; CHECK-NEXT: Grouped accesses: 12; CHECK-EMPTY: 13; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 14; CHECK-NEXT: SCEV assumptions: 15; CHECK-EMPTY: 16; CHECK-NEXT: Expressions re-written: 17; 18 %c = icmp eq i64 %off, 100 19 br i1 %c, label %ph, label %exit 20 21ph: 22 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off 23 br label %loop 24 25loop: 26 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 27 %l = load i32 , ptr %gep.after, align 4 28 %add = add i32 %l, %l 29 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 30 store i32 %add, ptr %gep, align 4 31 %iv.next = add nsw nuw i64 %iv, 1 32 %ec = icmp eq i64 %iv.next, 100 33 br i1 %ec, label %exit, label %loop 34 35exit: 36 ret void 37} 38 39; Loop guard for %off guarantees the accesses in the loop do not overlap. 40; TODO: currently missed by LAA 41define void @access_after_via_loop_guard_sge(ptr %a, i64 %off) { 42; CHECK-LABEL: 'access_after_via_loop_guard_sge' 43; CHECK-NEXT: loop: 44; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 45; CHECK-NEXT: Unknown data dependence. 46; CHECK-NEXT: Dependences: 47; CHECK-NEXT: Unknown: 48; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 49; CHECK-NEXT: store i32 %add, ptr %gep, align 4 50; CHECK-EMPTY: 51; CHECK-NEXT: Run-time memory checks: 52; CHECK-NEXT: Grouped accesses: 53; CHECK-EMPTY: 54; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 55; CHECK-NEXT: SCEV assumptions: 56; CHECK-EMPTY: 57; CHECK-NEXT: Expressions re-written: 58; 59 %c = icmp sge i64 %off, 100 60 br i1 %c, label %ph, label %exit 61 62ph: 63 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off 64 br label %loop 65 66loop: 67 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 68 %l = load i32 , ptr %gep.after, align 4 69 %add = add i32 %l, %l 70 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 71 store i32 %add, ptr %gep, align 4 72 %iv.next = add nsw nuw i64 %iv, 1 73 %ec = icmp eq i64 %iv.next, 100 74 br i1 %ec, label %exit, label %loop 75 76exit: 77 ret void 78} 79 80define void @access_after_via_loop_guard_99(ptr %a, i64 %off) { 81; CHECK-LABEL: 'access_after_via_loop_guard_99' 82; CHECK-NEXT: loop: 83; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 84; CHECK-NEXT: Unknown data dependence. 85; CHECK-NEXT: Dependences: 86; CHECK-NEXT: Unknown: 87; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 88; CHECK-NEXT: store i32 %add, ptr %gep, align 4 89; CHECK-EMPTY: 90; CHECK-NEXT: Run-time memory checks: 91; CHECK-NEXT: Grouped accesses: 92; CHECK-EMPTY: 93; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 94; CHECK-NEXT: SCEV assumptions: 95; CHECK-EMPTY: 96; CHECK-NEXT: Expressions re-written: 97; 98 %c = icmp eq i64 %off, 99 99 br i1 %c, label %ph, label %exit 100 101ph: 102 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off 103 br label %loop 104 105loop: 106 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 107 %l = load i32 , ptr %gep.after, align 4 108 %add = add i32 %l, %l 109 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 110 store i32 %add, ptr %gep, align 4 111 %iv.next = add nsw nuw i64 %iv, 1 112 %ec = icmp eq i64 %iv.next, 100 113 br i1 %ec, label %exit, label %loop 114 115exit: 116 ret void 117} 118 119; Loop guard for %off guarantees the accesses in the loop do not overlap. 120; TODO: currently missed by LAA 121define void @access_after_via_loop_guard_sge_99(ptr %a, i64 %off) { 122; CHECK-LABEL: 'access_after_via_loop_guard_sge_99' 123; CHECK-NEXT: loop: 124; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 125; CHECK-NEXT: Unknown data dependence. 126; CHECK-NEXT: Dependences: 127; CHECK-NEXT: Unknown: 128; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 129; CHECK-NEXT: store i32 %add, ptr %gep, align 4 130; CHECK-EMPTY: 131; CHECK-NEXT: Run-time memory checks: 132; CHECK-NEXT: Grouped accesses: 133; CHECK-EMPTY: 134; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 135; CHECK-NEXT: SCEV assumptions: 136; CHECK-EMPTY: 137; CHECK-NEXT: Expressions re-written: 138; 139 %c = icmp sge i64 %off, 99 140 br i1 %c, label %ph, label %exit 141 142ph: 143 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off 144 br label %loop 145 146loop: 147 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 148 %l = load i32 , ptr %gep.after, align 4 149 %add = add i32 %l, %l 150 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 151 store i32 %add, ptr %gep, align 4 152 %iv.next = add nsw nuw i64 %iv, 1 153 %ec = icmp eq i64 %iv.next, 100 154 br i1 %ec, label %exit, label %loop 155 156exit: 157 ret void 158} 159 160define void @access_after_via_loop_guard_uge(ptr %a, i64 %off) { 161; CHECK-LABEL: 'access_after_via_loop_guard_uge' 162; CHECK-NEXT: loop: 163; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 164; CHECK-NEXT: Unknown data dependence. 165; CHECK-NEXT: Dependences: 166; CHECK-NEXT: Unknown: 167; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 168; CHECK-NEXT: store i32 %add, ptr %gep, align 4 169; CHECK-EMPTY: 170; CHECK-NEXT: Run-time memory checks: 171; CHECK-NEXT: Grouped accesses: 172; CHECK-EMPTY: 173; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 174; CHECK-NEXT: SCEV assumptions: 175; CHECK-EMPTY: 176; CHECK-NEXT: Expressions re-written: 177; 178 %c = icmp uge i64 %off, 100 179 br i1 %c, label %ph, label %exit 180 181ph: 182 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off 183 br label %loop 184 185loop: 186 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 187 %l = load i32 , ptr %gep.after, align 4 188 %add = add i32 %l, %l 189 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 190 store i32 %add, ptr %gep, align 4 191 %iv.next = add nsw nuw i64 %iv, 1 192 %ec = icmp eq i64 %iv.next, 100 193 br i1 %ec, label %exit, label %loop 194 195exit: 196 ret void 197} 198 199; Loop guard for %off guarantees the accesses in the loop do not overlap. 200define void @access_after_via_loop_guard_eq_loop_cond(ptr %a, i64 %off) { 201; CHECK-LABEL: 'access_after_via_loop_guard_eq_loop_cond' 202; CHECK-NEXT: loop: 203; CHECK-NEXT: Memory dependences are safe 204; CHECK-NEXT: Dependences: 205; CHECK-NEXT: Run-time memory checks: 206; CHECK-NEXT: Grouped accesses: 207; CHECK-EMPTY: 208; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 209; CHECK-NEXT: SCEV assumptions: 210; CHECK-EMPTY: 211; CHECK-NEXT: Expressions re-written: 212; 213 %c = icmp eq i64 %off, 100 214 br i1 %c, label %ph, label %exit 215 216ph: 217 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100 218 br label %loop 219 220loop: 221 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 222 %l = load i32 , ptr %gep.after, align 4 223 %add = add i32 %l, %l 224 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 225 store i32 %add, ptr %gep, align 4 226 %iv.next = add nsw nuw i64 %iv, 1 227 %ec = icmp eq i64 %iv.next, %off 228 br i1 %ec, label %exit, label %loop 229 230exit: 231 ret void 232} 233 234define void @access_after_via_loop_guard_eq_loop_cond_100(ptr %a, i64 %off) { 235; CHECK-LABEL: 'access_after_via_loop_guard_eq_loop_cond_100' 236; CHECK-NEXT: loop: 237; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 238; CHECK-NEXT: Unknown data dependence. 239; CHECK-NEXT: Dependences: 240; CHECK-NEXT: Unknown: 241; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 242; CHECK-NEXT: store i32 %add, ptr %gep, align 4 243; CHECK-EMPTY: 244; CHECK-NEXT: Run-time memory checks: 245; CHECK-NEXT: Grouped accesses: 246; CHECK-EMPTY: 247; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 248; CHECK-NEXT: SCEV assumptions: 249; CHECK-EMPTY: 250; CHECK-NEXT: Expressions re-written: 251; 252 %c = icmp eq i64 %off, 101 253 br i1 %c, label %ph, label %exit 254 255ph: 256 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100 257 br label %loop 258 259loop: 260 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 261 %l = load i32 , ptr %gep.after, align 4 262 %add = add i32 %l, %l 263 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 264 store i32 %add, ptr %gep, align 4 265 %iv.next = add nsw nuw i64 %iv, 1 266 %ec = icmp eq i64 %iv.next, %off 267 br i1 %ec, label %exit, label %loop 268 269exit: 270 ret void 271} 272 273; Loop guard for %off guarantees the accesses in the loop do not overlap. 274; TODO: currently missed by LAA 275define void @access_after_via_loop_guard_sge_loop_cond(ptr %a, i64 %off) { 276; CHECK-LABEL: 'access_after_via_loop_guard_sge_loop_cond' 277; CHECK-NEXT: loop: 278; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 279; CHECK-NEXT: Unknown data dependence. 280; CHECK-NEXT: Dependences: 281; CHECK-NEXT: Unknown: 282; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 283; CHECK-NEXT: store i32 %add, ptr %gep, align 4 284; CHECK-EMPTY: 285; CHECK-NEXT: Run-time memory checks: 286; CHECK-NEXT: Grouped accesses: 287; CHECK-EMPTY: 288; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 289; CHECK-NEXT: SCEV assumptions: 290; CHECK-EMPTY: 291; CHECK-NEXT: Expressions re-written: 292; 293 %c = icmp sge i64 %off, 100 294 br i1 %c, label %ph, label %exit 295 296ph: 297 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100 298 br label %loop 299 300loop: 301 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 302 %l = load i32 , ptr %gep.after, align 4 303 %add = add i32 %l, %l 304 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 305 store i32 %add, ptr %gep, align 4 306 %iv.next = add nsw nuw i64 %iv, 1 307 %ec = icmp eq i64 %iv.next, %off 308 br i1 %ec, label %exit, label %loop 309 310exit: 311 ret void 312} 313 314define void @access_after_via_loop_guard_sge_loop_cond_101(ptr %a, i64 %off) { 315; CHECK-LABEL: 'access_after_via_loop_guard_sge_loop_cond_101' 316; CHECK-NEXT: loop: 317; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop 318; CHECK-NEXT: Unknown data dependence. 319; CHECK-NEXT: Dependences: 320; CHECK-NEXT: Unknown: 321; CHECK-NEXT: %l = load i32, ptr %gep.after, align 4 -> 322; CHECK-NEXT: store i32 %add, ptr %gep, align 4 323; CHECK-EMPTY: 324; CHECK-NEXT: Run-time memory checks: 325; CHECK-NEXT: Grouped accesses: 326; CHECK-EMPTY: 327; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 328; CHECK-NEXT: SCEV assumptions: 329; CHECK-EMPTY: 330; CHECK-NEXT: Expressions re-written: 331; 332 %c = icmp sge i64 %off, 101 333 br i1 %c, label %ph, label %exit 334 335ph: 336 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100 337 br label %loop 338 339loop: 340 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 341 %l = load i32 , ptr %gep.after, align 4 342 %add = add i32 %l, %l 343 %gep = getelementptr inbounds i32, ptr %a, i64 %iv 344 store i32 %add, ptr %gep, align 4 345 %iv.next = add nsw nuw i64 %iv, 1 346 %ec = icmp eq i64 %iv.next, %off 347 br i1 %ec, label %exit, label %loop 348 349exit: 350 ret void 351} 352