293 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 32; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"5 6; Test cases for https://github.com/llvm/llvm-project/issues/69744.7; Note that both loops in the tests are needed to incorrectly determine that8; the loops are safe with runtime checks via FoundNonConstantDistanceDependence9; handling code in LAA.10 11define void @test_indirect_read_write_loop_also_modifies_pointer_array(ptr noundef %arr) {12; CHECK-LABEL: 'test_indirect_read_write_loop_also_modifies_pointer_array'13; CHECK-NEXT: loop.1:14; CHECK-NEXT: Report: could not determine number of loop iterations15; CHECK-NEXT: Dependences:16; CHECK-NEXT: Run-time memory checks:17; CHECK-NEXT: Grouped accesses:18; CHECK-EMPTY:19; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.20; CHECK-NEXT: SCEV assumptions:21; CHECK-EMPTY:22; CHECK-NEXT: Expressions re-written:23; CHECK-NEXT: loop.2:24; 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 loop25; CHECK-NEXT: Unsafe indirect dependence.26; CHECK-NEXT: Dependences:27; CHECK-NEXT: IndirectUnsafe:28; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !4 ->29; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !430; CHECK-EMPTY:31; CHECK-NEXT: Unknown:32; CHECK-NEXT: %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !0 ->33; CHECK-NEXT: store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !034; CHECK-EMPTY:35; CHECK-NEXT: Run-time memory checks:36; CHECK-NEXT: Grouped accesses:37; CHECK-EMPTY:38; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.39; CHECK-NEXT: SCEV assumptions:40; CHECK-EMPTY:41; CHECK-NEXT: Expressions re-written:42;43entry:44 br label %loop.145 46loop.1:47 %iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]48 %arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]49 %incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 150 %0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !651 %tobool.not.i = icmp eq ptr %0, null52 %iv.next = add i64 %iv, 853 br i1 %tobool.not.i, label %loop.1.exit, label %loop.154 55loop.1.exit:56 %iv.lcssa = phi i64 [ %iv, %loop.1 ]57 br label %loop.258 59loop.2:60 %iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]61 %iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]62 %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.163 %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !664 %l.2 = load i64, ptr %l.1, align 8, !tbaa !1365 %inc = add i64 %l.2, 166 store i64 %inc, ptr %l.1, align 8, !tbaa !1367 %iv.2.next = add nsw i64 %iv.2, 168 %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.269 store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !670 %iv.1.next = add nuw nsw i64 %iv.1, 171 %cmp = icmp ult i64 %iv.1.next, 100072 br i1 %cmp, label %loop.2, label %exit73 74exit:75 ret void76}77 78define void @test_indirect_read_loop_also_modifies_pointer_array(ptr noundef %arr) {79; CHECK-LABEL: 'test_indirect_read_loop_also_modifies_pointer_array'80; CHECK-NEXT: loop.1:81; CHECK-NEXT: Report: could not determine number of loop iterations82; CHECK-NEXT: Dependences:83; CHECK-NEXT: Run-time memory checks:84; CHECK-NEXT: Grouped accesses:85; CHECK-EMPTY:86; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.87; CHECK-NEXT: SCEV assumptions:88; CHECK-EMPTY:89; CHECK-NEXT: Expressions re-written:90; CHECK-NEXT: loop.2:91; CHECK-NEXT: Memory dependences are safe with run-time checks92; CHECK-NEXT: Dependences:93; CHECK-NEXT: Run-time memory checks:94; CHECK-NEXT: Check 0:95; CHECK-NEXT: Comparing group GRP0:96; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i64, ptr %arr, i64 %iv.297; CHECK-NEXT: Against group GRP1:98; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.199; CHECK-NEXT: Grouped accesses:100; CHECK-NEXT: Group GRP0:101; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)102; CHECK-NEXT: Member: {{\{\{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>103; CHECK-NEXT: Group GRP1:104; CHECK-NEXT: (Low: %arr High: (8000 + %arr))105; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>106; CHECK-EMPTY:107; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.108; CHECK-NEXT: SCEV assumptions:109; CHECK-EMPTY:110; CHECK-NEXT: Expressions re-written:111;112entry:113 br label %loop.1114 115loop.1:116 %iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]117 %arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]118 %incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1119 %0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6120 %tobool.not.i = icmp eq ptr %0, null121 %iv.next = add i64 %iv, 8122 br i1 %tobool.not.i, label %loop.1.exit, label %loop.1123 124loop.1.exit:125 %iv.lcssa = phi i64 [ %iv, %loop.1 ]126 br label %loop.2127 128loop.2:129 %iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]130 %iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]131 %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1132 %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6133 %l.2 = load i64, ptr %l.1, align 8, !tbaa !13134 %inc = add i64 %l.2, 1135 %iv.2.next = add nsw i64 %iv.2, 1136 %gep.iv.2 = getelementptr inbounds i64, ptr %arr, i64 %iv.2137 store i64 %l.2, ptr %gep.iv.2, align 8, !tbaa !6138 %iv.1.next = add nuw nsw i64 %iv.1, 1139 %cmp = icmp ult i64 %iv.1.next, 1000140 br i1 %cmp, label %loop.2, label %exit141 142exit:143 ret void144}145 146define void @test_indirect_write_loop_also_modifies_pointer_array(ptr noundef %arr) {147; CHECK-LABEL: 'test_indirect_write_loop_also_modifies_pointer_array'148; CHECK-NEXT: loop.1:149; CHECK-NEXT: Report: could not determine number of loop iterations150; CHECK-NEXT: Dependences:151; CHECK-NEXT: Run-time memory checks:152; CHECK-NEXT: Grouped accesses:153; CHECK-EMPTY:154; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.155; CHECK-NEXT: SCEV assumptions:156; CHECK-EMPTY:157; CHECK-NEXT: Expressions re-written:158; CHECK-NEXT: loop.2:159; CHECK-NEXT: Memory dependences are safe with run-time checks160; CHECK-NEXT: Dependences:161; CHECK-NEXT: Run-time memory checks:162; CHECK-NEXT: Check 0:163; CHECK-NEXT: Comparing group GRP0:164; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2165; CHECK-NEXT: Against group GRP1:166; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1167; CHECK-NEXT: Grouped accesses:168; CHECK-NEXT: Group GRP0:169; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)170; CHECK-NEXT: Member: {{\{\{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>171; CHECK-NEXT: Group GRP1:172; CHECK-NEXT: (Low: %arr High: (8000 + %arr))173; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>174; CHECK-EMPTY:175; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.176; CHECK-NEXT: SCEV assumptions:177; CHECK-EMPTY:178; CHECK-NEXT: Expressions re-written:179;180entry:181 br label %loop.1182 183loop.1:184 %iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]185 %arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]186 %incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1187 %0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6188 %tobool.not.i = icmp eq ptr %0, null189 %iv.next = add i64 %iv, 8190 br i1 %tobool.not.i, label %loop.1.exit, label %loop.1191 192loop.1.exit:193 %iv.lcssa = phi i64 [ %iv, %loop.1 ]194 br label %loop.2195 196loop.2:197 %iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]198 %iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]199 %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1200 %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6201 %inc = add i64 %iv.1, 1202 store i64 %inc, ptr %l.1, align 8, !tbaa !13203 %iv.2.next = add nsw i64 %iv.2, 1204 %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2205 store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !6206 %iv.1.next = add nuw nsw i64 %iv.1, 1207 %cmp = icmp ult i64 %iv.1.next, 1000208 br i1 %cmp, label %loop.2, label %exit209 210exit:211 ret void212}213 214; FIXME: Not safe with runtime checks due to the indirect pointers are modified215; in the loop.216define void @test_indirect_read_write_loop_does_not_modify_pointer_array(ptr noundef %arr, ptr noundef noalias %arr2) {217; CHECK-LABEL: 'test_indirect_read_write_loop_does_not_modify_pointer_array'218; CHECK-NEXT: loop.1:219; CHECK-NEXT: Report: could not determine number of loop iterations220; CHECK-NEXT: Dependences:221; CHECK-NEXT: Run-time memory checks:222; CHECK-NEXT: Grouped accesses:223; CHECK-EMPTY:224; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.225; CHECK-NEXT: SCEV assumptions:226; CHECK-EMPTY:227; CHECK-NEXT: Expressions re-written:228; CHECK-NEXT: loop.2:229; 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 loop230; CHECK-NEXT: Unsafe indirect dependence.231; CHECK-NEXT: Dependences:232; CHECK-NEXT: IndirectUnsafe:233; CHECK-NEXT: %l.2 = load i64, ptr %l.1, align 8, !tbaa !4 ->234; CHECK-NEXT: store i64 %inc, ptr %l.1, align 8, !tbaa !4235; CHECK-EMPTY:236; CHECK-NEXT: Unknown:237; CHECK-NEXT: %l.3 = load i64, ptr %gep.arr2.iv.1, align 8 ->238; CHECK-NEXT: store i64 %inc.2, ptr %gep.arr2.iv.2, align 8, !tbaa !0239; CHECK-EMPTY:240; CHECK-NEXT: Run-time memory checks:241; CHECK-NEXT: Grouped accesses:242; CHECK-EMPTY:243; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.244; CHECK-NEXT: SCEV assumptions:245; CHECK-EMPTY:246; CHECK-NEXT: Expressions re-written:247;248entry:249 br label %loop.1250 251loop.1:252 %iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]253 %arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]254 %incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1255 %0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6256 %tobool.not.i = icmp eq ptr %0, null257 %iv.next = add i64 %iv, 8258 br i1 %tobool.not.i, label %loop.1.exit, label %loop.1259 260loop.1.exit:261 %iv.lcssa = phi i64 [ %iv, %loop.1 ]262 br label %loop.2263 264loop.2:265 %iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]266 %iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]267 %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1268 %l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6269 %l.2 = load i64, ptr %l.1, align 8, !tbaa !13270 %inc = add i64 %l.2, 1271 store i64 %inc, ptr %l.1, align 8, !tbaa !13272 %iv.2.next = add nsw i64 %iv.2, 1273 %gep.arr2.iv.1 = getelementptr inbounds i64 , ptr %arr2, i64 %iv.1274 %gep.arr2.iv.2 = getelementptr inbounds i64 , ptr %arr2, i64 %iv.2275 %l.3 = load i64, ptr %gep.arr2.iv.1276 %inc.2 = add i64 %l.3, 5277 store i64 %inc.2, ptr %gep.arr2.iv.2, align 8, !tbaa !6278 %iv.1.next = add nuw nsw i64 %iv.1, 1279 %cmp = icmp ult i64 %iv.1.next, 1000280 br i1 %cmp, label %loop.2, label %exit281 282exit:283 ret void284}285 286!6 = !{!7, !7, i64 0}287!7 = !{!"any pointer", !8, i64 0}288!8 = !{!"omnipotent char", !9, i64 0}289!9 = !{!"Simple C/C++ TBAA"}290!13 = !{!14, !15, i64 0}291!14 = !{!"", !15, i64 0}292!15 = !{!"long long", !8, i64 0}293