139 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; Analyze this loop:5; for (i = 0; i < n; i++)6; A[i + 1] = A[i] * B[i] * C[i];7 8; In this case, runtime checks are needed, and there is a convergent operation.9define void @rtchecks_needed(ptr %a, ptr %b, ptr %c) {10; CHECK-LABEL: 'rtchecks_needed'11; CHECK-NEXT: for.body:12; CHECK-NEXT: Has convergent operation in loop13; CHECK-NEXT: Report: cannot add control dependency to convergent operation14; CHECK-NEXT: Dependences:15; CHECK-NEXT: Backward:16; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 2 ->17; CHECK-NEXT: store i16 %mul1, ptr %arrayidxA_plus_2, align 218; CHECK-EMPTY:19; CHECK-NEXT: Run-time memory checks:20; CHECK-NEXT: Check 0:21; CHECK-NEXT: Comparing group GRP0:22; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge323; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add24; CHECK-NEXT: Against group GRP1:25; CHECK-NEXT: %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge326; CHECK-NEXT: Check 1:27; CHECK-NEXT: Comparing group GRP0:28; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge329; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add30; CHECK-NEXT: Against group GRP2:31; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge332; CHECK-NEXT: Grouped accesses:33; CHECK-NEXT: Group GRP0:34; CHECK-NEXT: (Low: %a High: (42 + %a))35; CHECK-NEXT: Member: {%a,+,2}<nuw><%for.body>36; CHECK-NEXT: Member: {(2 + %a),+,2}<nw><%for.body>37; CHECK-NEXT: Group GRP1:38; CHECK-NEXT: (Low: %b High: (40 + %b))39; CHECK-NEXT: Member: {%b,+,2}<nuw><%for.body>40; CHECK-NEXT: Group GRP2:41; CHECK-NEXT: (Low: %c High: (40 + %c))42; CHECK-NEXT: Member: {%c,+,2}<nuw><%for.body>43; CHECK-EMPTY:44; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.45; CHECK-NEXT: SCEV assumptions:46; CHECK-EMPTY:47; CHECK-NEXT: Expressions re-written:48;49entry:50 br label %for.body51 52for.body: ; preds = %for.body, %entry53 %storemerge3 = phi i64 [ 0, %entry ], [ %add, %for.body ]54 55 %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge356 %loadA = load i16, ptr %arrayidxA, align 257 58 %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge359 %loadB = load i16, ptr %arrayidxB, align 260 61 %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge362 %loadC = load i16, ptr %arrayidxC, align 263 64 call i16 @llvm.convergent(i16 %loadC)65 66 %mul = mul i16 %loadB, %loadA67 %mul1 = mul i16 %mul, %loadC68 69 %add = add nuw nsw i64 %storemerge3, 170 %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add71 store i16 %mul1, ptr %arrayidxA_plus_2, align 272 73 %exitcond = icmp eq i64 %add, 2074 br i1 %exitcond, label %for.end, label %for.body75 76for.end: ; preds = %for.body77 ret void78}79 80; In this case, no runtime checks are needed, and there is a convergent operation.81define void @no_rtchecks(ptr noalias %a, ptr noalias %b, ptr noalias %c, ptr noalias %d, ptr noalias %e) {82; CHECK-LABEL: 'no_rtchecks'83; CHECK-NEXT: for.body:84; CHECK-NEXT: Has convergent operation in loop85; CHECK-NEXT: Report: cannot add control dependency to convergent operation86; CHECK-NEXT: Dependences:87; CHECK-NEXT: Backward:88; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 4 ->89; CHECK-NEXT: store i16 %mulA, ptr %arrayidxA_plus_4, align 490; CHECK-EMPTY:91; CHECK-NEXT: Run-time memory checks:92; CHECK-NEXT: Grouped accesses:93; CHECK-EMPTY:94; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.95; CHECK-NEXT: SCEV assumptions:96; CHECK-EMPTY:97; CHECK-NEXT: Expressions re-written:98;99entry:100 br label %for.body101 102for.body: ; preds = %for.body, %entry103 %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]104 105 %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %ind106 %loadA = load i16, ptr %arrayidxA, align 4107 108 %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %ind109 %loadB = load i16, ptr %arrayidxB, align 4110 111 %mulA = mul i16 %loadB, %loadA112 113 %add = add nuw nsw i64 %ind, 1114 %arrayidxA_plus_4 = getelementptr inbounds i16, ptr %a, i64 %add115 store i16 %mulA, ptr %arrayidxA_plus_4, align 4116 117 %arrayidxD = getelementptr inbounds i16, ptr %d, i64 %ind118 %loadD = load i16, ptr %arrayidxD, align 4119 120 %arrayidxE = getelementptr inbounds i16, ptr %e, i64 %ind121 %loadE = load i16, ptr %arrayidxE, align 4122 123 %convergentD = call i16 @llvm.convergent(i16 %loadD)124 %mulC = mul i16 %convergentD, %loadE125 126 %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %ind127 store i16 %mulC, ptr %arrayidxC, align 4128 129 %exitcond = icmp eq i64 %add, 20130 br i1 %exitcond, label %for.end, label %for.body131 132for.end: ; preds = %for.body133 ret void134}135 136declare i16 @llvm.convergent(i16) #0137 138attributes #0 = { nounwind readnone convergent }139