diff --git a/llvm/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-convergent.ll b/llvm/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-convergent.ll index 4876c5c4b26f8..d0b101079efbf 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-convergent.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-convergent.ll @@ -1,41 +1,52 @@ -; RUN: opt -passes='print' -disable-output < %s 2>&1 | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes='print' -disable-output %s 2>&1 | FileCheck %s ; Analyze this loop: ; for (i = 0; i < n; i++) ; A[i + 1] = A[i] * B[i] * C[i]; -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - -; CHECK: for.body: -; CHECK: Has convergent operation in loop -; CHECK: Report: cannot add control dependency to convergent operation -; CHECK-NEXT: Dependences: -; CHECK-NEXT: Backward: -; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 2 -> -; CHECK-NEXT: store i16 %mul1, ptr %arrayidxA_plus_2, align 2 -; CHECK: Run-time memory checks: -; CHECK-NEXT: 0: -; CHECK-NEXT: Comparing group -; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3 -; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add -; CHECK-NEXT: Against group -; CHECK-NEXT: %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge3 -; CHECK-NEXT: 1: -; CHECK-NEXT: Comparing group -; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3 -; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add -; CHECK-NEXT: Against group -; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge3 - -@B = common global ptr null, align 8 -@A = common global ptr null, align 8 -@C = common global ptr null, align 8 - -define void @f() #1 { +; In this case, runtime checks are needed, and there is a convergent operation. +define void @rtchecks_needed(ptr %a, ptr %b, ptr %c) { +; CHECK-LABEL: 'rtchecks_needed' +; CHECK-NEXT: for.body: +; CHECK-NEXT: Has convergent operation in loop +; CHECK-NEXT: Report: cannot add control dependency to convergent operation +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Backward: +; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 2 -> +; CHECK-NEXT: store i16 %mul1, ptr %arrayidxA_plus_2, align 2 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Check 0: +; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]): +; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3 +; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add +; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]): +; CHECK-NEXT: %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge3 +; CHECK-NEXT: Check 1: +; CHECK-NEXT: Comparing group ([[GRP1]]): +; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3 +; CHECK-NEXT: %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add +; CHECK-NEXT: Against group ([[GRP3:0x[0-9a-f]+]]): +; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge3 +; CHECK-NEXT: Grouped accesses: +; CHECK-NEXT: Group [[GRP1]]: +; CHECK-NEXT: (Low: %a High: (42 + %a)) +; CHECK-NEXT: Member: {%a,+,2}<%for.body> +; CHECK-NEXT: Member: {(2 + %a),+,2}<%for.body> +; CHECK-NEXT: Group [[GRP2]]: +; CHECK-NEXT: (Low: %b High: (40 + %b)) +; CHECK-NEXT: Member: {%b,+,2}<%for.body> +; CHECK-NEXT: Group [[GRP3]]: +; CHECK-NEXT: (Low: %c High: (40 + %c)) +; CHECK-NEXT: Member: {%c,+,2}<%for.body> +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; entry: - %a = load ptr, ptr @A, align 8 - %b = load ptr, ptr @B, align 8 - %c = load ptr, ptr @C, align 8 br label %for.body for.body: ; preds = %for.body, %entry @@ -50,7 +61,7 @@ for.body: ; preds = %for.body, %entry %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge3 %loadC = load i16, ptr %arrayidxC, align 2 - call void @llvm.convergent() + call i16 @llvm.convergent(i16 %loadC) %mul = mul i16 %loadB, %loadA %mul1 = mul i16 %mul, %loadC @@ -66,7 +77,62 @@ for.end: ; preds = %for.body ret void } -declare void @llvm.convergent() #0 +; In this case, no runtime checks are needed, and there is a convergent operation. +define void @no_rtchecks(ptr noalias %a, ptr noalias %b, ptr noalias %c, ptr noalias %d, ptr noalias %e) { +; CHECK-LABEL: 'no_rtchecks' +; CHECK-NEXT: for.body: +; CHECK-NEXT: Has convergent operation in loop +; CHECK-NEXT: Report: cannot add control dependency to convergent operation +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Backward: +; CHECK-NEXT: %loadA = load i16, ptr %arrayidxA, align 4 -> +; CHECK-NEXT: store i16 %mulA, ptr %arrayidxA_plus_4, align 4 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %ind = phi i64 [ 0, %entry ], [ %add, %for.body ] + + %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %ind + %loadA = load i16, ptr %arrayidxA, align 4 + + %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %ind + %loadB = load i16, ptr %arrayidxB, align 4 + + %mulA = mul i16 %loadB, %loadA + + %add = add nuw nsw i64 %ind, 1 + %arrayidxA_plus_4 = getelementptr inbounds i16, ptr %a, i64 %add + store i16 %mulA, ptr %arrayidxA_plus_4, align 4 + + %arrayidxD = getelementptr inbounds i16, ptr %d, i64 %ind + %loadD = load i16, ptr %arrayidxD, align 4 + + %arrayidxE = getelementptr inbounds i16, ptr %e, i64 %ind + %loadE = load i16, ptr %arrayidxE, align 4 + + %convergentD = call i16 @llvm.convergent(i16 %loadD) + %mulC = mul i16 %convergentD, %loadE + + %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %ind + store i16 %mulC, ptr %arrayidxC, align 4 + + %exitcond = icmp eq i64 %add, 20 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +} + +declare i16 @llvm.convergent(i16) #0 attributes #0 = { nounwind readnone convergent } -attributes #1 = { nounwind convergent }