439 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s3 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 safe9; 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, 10019 br i1 %c, label %ph, label %exit20 21ph:22 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off23 br label %loop24 25loop:26 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]27 %l = load i32 , ptr %gep.after, align 428 %add = add i32 %l, %l29 %gep = getelementptr inbounds i32, ptr %a, i64 %iv30 store i32 %add, ptr %gep, align 431 %iv.next = add nsw nuw i64 %iv, 132 %ec = icmp eq i64 %iv.next, 10033 br i1 %ec, label %exit, label %loop34 35exit:36 ret void37}38 39; Loop guard for %off guarantees the accesses in the loop do not overlap.40; TODO: currently missed by LAA41define 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 loop45; 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 450; 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, 10060 br i1 %c, label %ph, label %exit61 62ph:63 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off64 br label %loop65 66loop:67 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]68 %l = load i32 , ptr %gep.after, align 469 %add = add i32 %l, %l70 %gep = getelementptr inbounds i32, ptr %a, i64 %iv71 store i32 %add, ptr %gep, align 472 %iv.next = add nsw nuw i64 %iv, 173 %ec = icmp eq i64 %iv.next, 10074 br i1 %ec, label %exit, label %loop75 76exit:77 ret void78}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 loop84; 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 489; 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, 9999 br i1 %c, label %ph, label %exit100 101ph:102 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off103 br label %loop104 105loop:106 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]107 %l = load i32 , ptr %gep.after, align 4108 %add = add i32 %l, %l109 %gep = getelementptr inbounds i32, ptr %a, i64 %iv110 store i32 %add, ptr %gep, align 4111 %iv.next = add nsw nuw i64 %iv, 1112 %ec = icmp eq i64 %iv.next, 100113 br i1 %ec, label %exit, label %loop114 115exit:116 ret void117}118 119; Loop guard for %off guarantees the accesses in the loop do not overlap.120; TODO: currently missed by LAA121define 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 loop125; 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 4130; 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, 99140 br i1 %c, label %ph, label %exit141 142ph:143 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off144 br label %loop145 146loop:147 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]148 %l = load i32 , ptr %gep.after, align 4149 %add = add i32 %l, %l150 %gep = getelementptr inbounds i32, ptr %a, i64 %iv151 store i32 %add, ptr %gep, align 4152 %iv.next = add nsw nuw i64 %iv, 1153 %ec = icmp eq i64 %iv.next, 100154 br i1 %ec, label %exit, label %loop155 156exit:157 ret void158}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 loop164; 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 4169; 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, 100179 br i1 %c, label %ph, label %exit180 181ph:182 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off183 br label %loop184 185loop:186 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]187 %l = load i32 , ptr %gep.after, align 4188 %add = add i32 %l, %l189 %gep = getelementptr inbounds i32, ptr %a, i64 %iv190 store i32 %add, ptr %gep, align 4191 %iv.next = add nsw nuw i64 %iv, 1192 %ec = icmp eq i64 %iv.next, 100193 br i1 %ec, label %exit, label %loop194 195exit:196 ret void197}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 safe204; 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, 100214 br i1 %c, label %ph, label %exit215 216ph:217 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100218 br label %loop219 220loop:221 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]222 %l = load i32 , ptr %gep.after, align 4223 %add = add i32 %l, %l224 %gep = getelementptr inbounds i32, ptr %a, i64 %iv225 store i32 %add, ptr %gep, align 4226 %iv.next = add nsw nuw i64 %iv, 1227 %ec = icmp eq i64 %iv.next, %off228 br i1 %ec, label %exit, label %loop229 230exit:231 ret void232}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 loop238; 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 4243; 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, 101253 br i1 %c, label %ph, label %exit254 255ph:256 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100257 br label %loop258 259loop:260 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]261 %l = load i32 , ptr %gep.after, align 4262 %add = add i32 %l, %l263 %gep = getelementptr inbounds i32, ptr %a, i64 %iv264 store i32 %add, ptr %gep, align 4265 %iv.next = add nsw nuw i64 %iv, 1266 %ec = icmp eq i64 %iv.next, %off267 br i1 %ec, label %exit, label %loop268 269exit:270 ret void271}272 273; Loop guard for %off guarantees the accesses in the loop do not overlap.274; TODO: currently missed by LAA275define 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 loop279; 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 4284; 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, 100294 br i1 %c, label %ph, label %exit295 296ph:297 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100298 br label %loop299 300loop:301 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]302 %l = load i32 , ptr %gep.after, align 4303 %add = add i32 %l, %l304 %gep = getelementptr inbounds i32, ptr %a, i64 %iv305 store i32 %add, ptr %gep, align 4306 %iv.next = add nsw nuw i64 %iv, 1307 %ec = icmp eq i64 %iv.next, %off308 br i1 %ec, label %exit, label %loop309 310exit:311 ret void312}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 loop318; 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 4323; 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, 101333 br i1 %c, label %ph, label %exit334 335ph:336 %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100337 br label %loop338 339loop:340 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]341 %l = load i32 , ptr %gep.after, align 4342 %add = add i32 %l, %l343 %gep = getelementptr inbounds i32, ptr %a, i64 %iv344 store i32 %add, ptr %gep, align 4345 %iv.next = add nsw nuw i64 %iv, 1346 %ec = icmp eq i64 %iv.next, %off347 br i1 %ec, label %exit, label %loop348 349exit:350 ret void351}352 353; TODO Should be able to determine no-dep, same as @nodep_via_logical_and_2.354define void @nodep_via_logical_and_1(ptr %A, i32 %index, i32 %n) {355; CHECK-LABEL: 'nodep_via_logical_and_1'356; CHECK-NEXT: loop:357; 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 loop358; CHECK-NEXT: Unknown data dependence.359; CHECK-NEXT: Dependences:360; CHECK-NEXT: Unknown:361; CHECK-NEXT: %0 = load double, ptr %gep.load, align 8 ->362; CHECK-NEXT: store double %0, ptr %gep.store, align 8363; CHECK-EMPTY:364; CHECK-NEXT: Run-time memory checks:365; CHECK-NEXT: Grouped accesses:366; CHECK-EMPTY:367; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.368; CHECK-NEXT: SCEV assumptions:369; CHECK-EMPTY:370; CHECK-NEXT: Expressions re-written:371;372entry:373 %pre.0 = icmp sgt i32 %index, 0374 %pre.1 = icmp slt i32 %index, %n375 %and.pre = select i1 %pre.1, i1 %pre.0, i1 false376 br i1 %and.pre, label %ph, label %exit377 378ph:379 %idx.1 = add i32 %index, 1380 %start = zext i32 %idx.1 to i64381 br label %loop382 383loop:384 %iv = phi i64 [ %start, %ph ], [ %iv.next, %loop ]385 %gep.load = getelementptr double, ptr %A, i64 %iv386 %1 = load double, ptr %gep.load, align 8387 %index.ext = zext i32 %index to i64388 %gep.store = getelementptr double, ptr %A, i64 %index.ext389 store double %1, ptr %gep.store, align 8390 %iv.next = add i64 %iv, 1391 %t = trunc i64 %iv to i32392 %ec = icmp slt i32 %t, 1393 br i1 %ec, label %loop, label %exit394 395exit:396 ret void397}398 399; Same as nodep_via_logical_and_1 but with different operand order of the logical and.400define void @nodep_via_logical_and_2(ptr %A, i32 %index, i32 %n) {401; CHECK-LABEL: 'nodep_via_logical_and_2'402; CHECK-NEXT: loop:403; CHECK-NEXT: Memory dependences are safe404; CHECK-NEXT: Dependences:405; CHECK-NEXT: Run-time memory checks:406; CHECK-NEXT: Grouped accesses:407; CHECK-EMPTY:408; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.409; CHECK-NEXT: SCEV assumptions:410; CHECK-EMPTY:411; CHECK-NEXT: Expressions re-written:412;413entry:414 %pre.0 = icmp sgt i32 %index, 0415 %pre.1 = icmp slt i32 %index, %n416 %and.pre = select i1 %pre.0, i1 %pre.1, i1 false417 br i1 %and.pre, label %ph, label %exit418 419ph:420 %idx.1 = add i32 %index, 1421 %start = zext i32 %idx.1 to i64422 br label %loop423 424loop:425 %iv = phi i64 [ %start, %ph ], [ %iv.next, %loop ]426 %gep.load = getelementptr double, ptr %A, i64 %iv427 %1 = load double, ptr %gep.load, align 8428 %index.ext = zext i32 %index to i64429 %gep.store = getelementptr double, ptr %A, i64 %index.ext430 store double %1, ptr %gep.store, align 8431 %iv.next = add i64 %iv, 1432 %t = trunc i64 %iv to i32433 %ec = icmp slt i32 %t, 1434 br i1 %ec, label %loop, label %exit435 436exit:437 ret void438}439