Skip to content

[SCEV] Add predicate in SolveLinEq to ensure B is a multiple of A. #108777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Sep 28, 2024

Conversation

fhahn
Copy link
Contributor

@fhahn fhahn commented Sep 15, 2024

This can help in cases where pointer alignment info is missing, e.g. #108210

The predicate is formed for the complex expression that's passed to SolveLinEquationWithOverflow and the checks could probably be pushed closer to the root nodes, which in some cases may be cheaper to check.

@llvmbot
Copy link
Member

llvmbot commented Sep 15, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

Changes

This can help in cases where pointer alignment info is missing, e.g. #108210

The predicate is formed for the complex expression that's passed to SolveLinEquationWithOverflow and the checks could probably be pushed closer to the root nodes, which in some cases may be cheaper to check.


Patch is 22.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108777.diff

4 Files Affected:

  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+19-6)
  • (modified) llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll (+17)
  • (modified) llvm/test/Analysis/ScalarEvolution/ne-overflow.ll (+72)
  • (modified) llvm/test/Transforms/LoopVectorize/opaque-ptr.ll (+73-11)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 57e03f667ba6ff..3fd07d2694d949 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10120,8 +10120,11 @@ const SCEV *ScalarEvolution::stripInjectiveFunctions(const SCEV *S) const {
 /// A and B isn't important.
 ///
 /// If the equation does not have a solution, SCEVCouldNotCompute is returned.
-static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
-                                               ScalarEvolution &SE) {
+static const SCEV *
+SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
+                             SmallPtrSetImpl<const SCEVPredicate *> *Predicates,
+
+                             ScalarEvolution &SE) {
   uint32_t BW = A.getBitWidth();
   assert(BW == SE.getTypeSizeInBits(B->getType()));
   assert(A != 0 && "A must be non-zero.");
@@ -10137,8 +10140,17 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
   //
   // B is divisible by D if and only if the multiplicity of prime factor 2 for B
   // is not less than multiplicity of this prime factor for D.
-  if (SE.getMinTrailingZeros(B) < Mult2)
-    return SE.getCouldNotCompute();
+  if (SE.getMinTrailingZeros(B) < Mult2) {
+    if (!Predicates)
+      return SE.getCouldNotCompute();
+    // Try to add a predicate ensuring B is a multiple of A.
+    const SCEV *URem = SE.getURemExpr(B, SE.getConstant(A));
+    const SCEV *Zero = SE.getZero(B->getType());
+    // Avoid adding a predicate that is known to be false.
+    if (SE.isKnownPredicate(CmpInst::ICMP_NE, URem, Zero))
+      return SE.getCouldNotCompute();
+    Predicates->insert(SE.getEqualPredicate(URem, Zero));
+  }
 
   // 3. Compute I: the multiplicative inverse of (A / D) in arithmetic
   // modulo (N / D).
@@ -10568,8 +10580,9 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
   // Solve the general equation.
   if (!StepC || StepC->getValue()->isZero())
     return getCouldNotCompute();
-  const SCEV *E = SolveLinEquationWithOverflow(StepC->getAPInt(),
-                                               getNegativeSCEV(Start), *this);
+  const SCEV *E = SolveLinEquationWithOverflow(
+      StepC->getAPInt(), getNegativeSCEV(Start),
+      AllowPredicates ? &Predicates : nullptr, *this);
 
   const SCEV *M = E;
   if (E != getCouldNotCompute()) {
diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
index 37d6584b1e85f1..302b2e4defd255 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -1580,6 +1580,12 @@ define i32 @ptr_induction_ult_2(ptr %a, ptr %b) {
 ; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
+; CHECK-NEXT:  Loop %loop: Predicated symbolic max backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
 ;
 entry:
   %cmp.6 = icmp ult ptr %a, %b
@@ -1669,10 +1675,21 @@ define void @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) {
 ; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
 ; CHECK-NEXT:    exit count for loop.inc: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
+; CHECK-EMPTY:
 ; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
 ; CHECK-NEXT:    symbolic max exit count for loop: ***COULDNOTCOMPUTE***
 ; CHECK-NEXT:    symbolic max exit count for loop.inc: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
+; CHECK-EMPTY:
+; CHECK-NEXT:  Loop %loop: Predicated symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
 ;
 entry:
   %cmp = icmp eq ptr %a, %b
diff --git a/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll b/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
index 49288c85897fd9..73679767f0fb3d 100644
--- a/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
@@ -58,6 +58,12 @@ define void @test_well_defined_infinite_st(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -79,6 +85,12 @@ define void @test_well_defined_infinite_ld(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -100,6 +112,12 @@ define void @test_no_mustprogress(i32 %N) {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -187,6 +205,12 @@ define void @test_abnormal_exit(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -209,10 +233,24 @@ define void @test_other_exit(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:    exit count for for.body: i32 9
 ; CHECK-NEXT:    exit count for for.latch: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated exit count for for.latch: ((-2 + %N) /u 2)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-EMPTY:
 ; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 9
 ; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is i32 9
 ; CHECK-NEXT:    symbolic max exit count for for.body: i32 9
 ; CHECK-NEXT:    symbolic max exit count for for.latch: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated symbolic max exit count for for.latch: ((-2 + %N) /u 2)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-EMPTY:
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (9 umin ((-2 + %N) /u 2))
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (9 umin ((-2 + %N) /u 2))
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -264,6 +302,14 @@ define void @test_sext(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -285,6 +331,16 @@ define void @test_zext_of_sext(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -307,6 +363,14 @@ define void @test_zext_offset(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -329,6 +393,14 @@ define void @test_sext_offset(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
 ;
 entry:
   br label %for.body
diff --git a/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll b/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
index 13e79a4a47b39c..f62c3c7f42ec4e 100644
--- a/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
+++ b/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
@@ -4,18 +4,80 @@
 define void @test_ptr_iv_no_inbounds(ptr %p1.start, ptr %p2.start, ptr %p1.end) {
 ; CHECK-LABEL: @test_ptr_iv_no_inbounds(
 ; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P1_START7:%.*]] = ptrtoint ptr [[P1_START:%.*]] to i64
+; CHECK-NEXT:    [[P1_END6:%.*]] = ptrtoint ptr [[P1_END:%.*]] to i64
+; CHECK-NEXT:    [[P1_START4:%.*]] = ptrtoint ptr [[P1_START]] to i64
+; CHECK-NEXT:    [[P1_END3:%.*]] = ptrtoint ptr [[P1_END]] to i64
+; CHECK-NEXT:    [[P1_START2:%.*]] = ptrtoint ptr [[P1_START]] to i64
+; CHECK-NEXT:    [[P1_END1:%.*]] = ptrtoint ptr [[P1_END]] to i64
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[P1_END6]], -4
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[P1_START7]]
+; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 1
+; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP3]], 2
+; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
+; CHECK:       vector.scevcheck:
+; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[P1_END1]] to i2
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[P1_START2]] to i2
+; CHECK-NEXT:    [[TMP6:%.*]] = sub i2 [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    [[TMP7:%.*]] = zext i2 [[TMP6]] to i64
+; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i64 [[TMP7]], 0
+; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]]
+; CHECK:       vector.memcheck:
+; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[P1_END3]], -4
+; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 [[TMP8]], [[P1_START4]]
+; CHECK-NEXT:    [[TMP10:%.*]] = lshr i64 [[TMP9]], 2
+; CHECK-NEXT:    [[TMP11:%.*]] = shl nuw i64 [[TMP10]], 2
+; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[TMP11]], 4
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP12]]
+; CHECK-NEXT:    [[SCEVGEP5:%.*]] = getelementptr i8, ptr [[P2_START:%.*]], i64 [[TMP12]]
+; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[P1_START]], [[SCEVGEP5]]
+; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[P2_START]], [[SCEVGEP]]
+; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
+; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
+; CHECK:       vector.ph:
+; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP3]], 2
+; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP3]], [[N_MOD_VF]]
+; CHECK-NEXT:    [[TMP13:%.*]] = mul i64 [[N_VEC]], 4
+; CHECK-NEXT:    [[IND_END:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP13]]
+; CHECK-NEXT:    [[TMP14:%.*]] = mul i64 [[N_VEC]], 4
+; CHECK-NEXT:    [[IND_END8:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP14]]
+; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
+; CHECK:       vector.body:
+; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 4
+; CHECK-NEXT:    [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 0
+; CHECK-NEXT:    [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP15]]
+; CHECK-NEXT:    [[OFFSET_IDX10:%.*]] = mul i64 [[INDEX]], 4
+; CHECK-NEXT:    [[TMP16:%.*]] = add i64 [[OFFSET_IDX10]], 0
+; CHECK-NEXT:    [[NEXT_GEP11:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP16]]
+; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr float, ptr [[NEXT_GEP]], i32 0
+; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP17]], align 4, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
+; CHECK-NEXT:    [[TMP18:%.*]] = getelementptr float, ptr [[NEXT_GEP11]], i32 0
+; CHECK-NEXT:    [[WIDE_LOAD12:%.*]] = load <2 x float>, ptr [[TMP18]], align 4, !alias.scope [[META3]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fadd <2 x float> [[WIDE_LOAD]], [[WIDE_LOAD12]]
+; CHECK-NEXT:    store <2 x float> [[TMP19]], ptr [[TMP17]], align 4, !alias.scope [[META0]], !noalias [[META3]]
+; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
+; CHECK-NEXT:    [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT:    br i1 [[TMP20]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
+; CHECK:       middle.block:
+; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[N_VEC]]
+; CHECK-NEXT:    br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK:       scalar.ph:
+; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi ptr [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[P1_START]], [[ENTRY:%.*]] ], [ [[P1_START]], [[VECTOR_SCEVCHECK]] ], [ [[P1_START]], [[VECTOR_MEMCHECK]] ]
+; CHECK-NEXT:    [[BC_RESUME_VAL9:%.*]] = phi ptr [ [[IND_END8]], [[MIDDLE_BLOCK]] ], [ [[P2_START]], [[ENTRY]] ], [ [[P2_START]], [[VECTOR_SCEVCHECK]] ], [ [[P2_START]], [[VECTOR_MEMCHECK]] ]
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK-NEXT:    [[P1:%.*]] = phi ptr [ [[P1_START:%.*]], [[ENTRY:%.*]] ], [ [[P1_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[P2:%.*]] = phi ptr [ [[P2_START:%.*]], [[ENTRY]] ], [ [[P2_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[P1:%.*]] = phi ptr [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[P1_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[P2:%.*]] = phi ptr [ [[BC_RESUME_VAL9]], [[SCALAR_PH]] ], [ [[P2_NEXT:%.*]], [[LOOP]] ]
 ; CHECK-NEXT:    [[P1_VAL:%.*]] = load float, ptr [[P1]], align 4
 ; CHECK-NEXT:    [[P2_VAL:%.*]] = load float, ptr [[P2]], align 4
 ; CHECK-NEXT:    [[SUM:%.*]] = fadd float [[P1_VAL]], [[P2_VAL]]
 ; CHECK-NEXT:    store float [[SUM]], ptr [[P1]], align 4
 ; CHECK-NEXT:    [[P1_NEXT]] = getelementptr float, ptr [[P1]], i64 1
 ; CHECK-NEXT:    [[P2_NEXT]] = getelementptr float, ptr [[P2]], i64 1
-; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P1_NEXT]], [[P1_END:%.*]]
-; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P1_NEXT]], [[P1_END]]
+; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP8:![0-9]+]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
@@ -80,14 +142,14 @@ define void @test_ptr_iv_with_inbounds(ptr %p1.start, ptr %p2.start, ptr %p1.end
 ; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[OFFSET_IDX8]], 0
 ; CHECK-NEXT:    [[NEXT_GEP9:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP12]]
 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr float, ptr [[NEXT_GEP]], i32 0
-; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP13]], align 4, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
+; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP13]], align 4, !alias.scope [[META9:![0-9]+]], !noalias [[META12:![0-9]+]]
 ; CHECK-NEXT:    [[TMP14:%...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Sep 15, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Florian Hahn (fhahn)

Changes

This can help in cases where pointer alignment info is missing, e.g. #108210

The predicate is formed for the complex expression that's passed to SolveLinEquationWithOverflow and the checks could probably be pushed closer to the root nodes, which in some cases may be cheaper to check.


Patch is 22.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108777.diff

4 Files Affected:

  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+19-6)
  • (modified) llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll (+17)
  • (modified) llvm/test/Analysis/ScalarEvolution/ne-overflow.ll (+72)
  • (modified) llvm/test/Transforms/LoopVectorize/opaque-ptr.ll (+73-11)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 57e03f667ba6ff..3fd07d2694d949 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10120,8 +10120,11 @@ const SCEV *ScalarEvolution::stripInjectiveFunctions(const SCEV *S) const {
 /// A and B isn't important.
 ///
 /// If the equation does not have a solution, SCEVCouldNotCompute is returned.
-static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
-                                               ScalarEvolution &SE) {
+static const SCEV *
+SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
+                             SmallPtrSetImpl<const SCEVPredicate *> *Predicates,
+
+                             ScalarEvolution &SE) {
   uint32_t BW = A.getBitWidth();
   assert(BW == SE.getTypeSizeInBits(B->getType()));
   assert(A != 0 && "A must be non-zero.");
@@ -10137,8 +10140,17 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
   //
   // B is divisible by D if and only if the multiplicity of prime factor 2 for B
   // is not less than multiplicity of this prime factor for D.
-  if (SE.getMinTrailingZeros(B) < Mult2)
-    return SE.getCouldNotCompute();
+  if (SE.getMinTrailingZeros(B) < Mult2) {
+    if (!Predicates)
+      return SE.getCouldNotCompute();
+    // Try to add a predicate ensuring B is a multiple of A.
+    const SCEV *URem = SE.getURemExpr(B, SE.getConstant(A));
+    const SCEV *Zero = SE.getZero(B->getType());
+    // Avoid adding a predicate that is known to be false.
+    if (SE.isKnownPredicate(CmpInst::ICMP_NE, URem, Zero))
+      return SE.getCouldNotCompute();
+    Predicates->insert(SE.getEqualPredicate(URem, Zero));
+  }
 
   // 3. Compute I: the multiplicative inverse of (A / D) in arithmetic
   // modulo (N / D).
@@ -10568,8 +10580,9 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
   // Solve the general equation.
   if (!StepC || StepC->getValue()->isZero())
     return getCouldNotCompute();
-  const SCEV *E = SolveLinEquationWithOverflow(StepC->getAPInt(),
-                                               getNegativeSCEV(Start), *this);
+  const SCEV *E = SolveLinEquationWithOverflow(
+      StepC->getAPInt(), getNegativeSCEV(Start),
+      AllowPredicates ? &Predicates : nullptr, *this);
 
   const SCEV *M = E;
   if (E != getCouldNotCompute()) {
diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
index 37d6584b1e85f1..302b2e4defd255 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -1580,6 +1580,12 @@ define i32 @ptr_induction_ult_2(ptr %a, ptr %b) {
 ; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
+; CHECK-NEXT:  Loop %loop: Predicated symbolic max backedge-taken count is (((-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 4)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i2 ((trunc i64 (ptrtoint ptr %b to i64) to i2) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i2))) to i64) == 0
 ;
 entry:
   %cmp.6 = icmp ult ptr %a, %b
@@ -1669,10 +1675,21 @@ define void @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) {
 ; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
 ; CHECK-NEXT:    exit count for loop.inc: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
+; CHECK-EMPTY:
 ; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
 ; CHECK-NEXT:    symbolic max exit count for loop: ***COULDNOTCOMPUTE***
 ; CHECK-NEXT:    symbolic max exit count for loop.inc: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
+; CHECK-EMPTY:
+; CHECK-NEXT:  Loop %loop: Predicated symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i3 ((trunc i64 (ptrtoint ptr %b to i64) to i3) + (-1 * (trunc i64 (ptrtoint ptr %a to i64) to i3))) to i64) == 0
 ;
 entry:
   %cmp = icmp eq ptr %a, %b
diff --git a/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll b/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
index 49288c85897fd9..73679767f0fb3d 100644
--- a/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
@@ -58,6 +58,12 @@ define void @test_well_defined_infinite_st(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -79,6 +85,12 @@ define void @test_well_defined_infinite_ld(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -100,6 +112,12 @@ define void @test_no_mustprogress(i32 %N) {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -187,6 +205,12 @@ define void @test_abnormal_exit(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-2 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -209,10 +233,24 @@ define void @test_other_exit(i32 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: <multiple exits> Unpredictable backedge-taken count.
 ; CHECK-NEXT:    exit count for for.body: i32 9
 ; CHECK-NEXT:    exit count for for.latch: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated exit count for for.latch: ((-2 + %N) /u 2)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-EMPTY:
 ; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 9
 ; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is i32 9
 ; CHECK-NEXT:    symbolic max exit count for for.body: i32 9
 ; CHECK-NEXT:    symbolic max exit count for for.latch: ***COULDNOTCOMPUTE***
+; CHECK-NEXT:    predicated symbolic max exit count for for.latch: ((-2 + %N) /u 2)
+; CHECK-NEXT:     Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-EMPTY:
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (9 umin ((-2 + %N) /u 2))
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (9 umin ((-2 + %N) /u 2))
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i32 %N to i1) to i32) == 0
 ;
 entry:
   br label %for.body
@@ -264,6 +302,14 @@ define void @test_sext(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -285,6 +331,16 @@ define void @test_zext_of_sext(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is (%N /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -307,6 +363,14 @@ define void @test_zext_offset(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nusw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
 ;
 entry:
   br label %for.body
@@ -329,6 +393,14 @@ define void @test_sext_offset(i64 %N) mustprogress {
 ; CHECK-NEXT:  Loop %for.body: Unpredictable backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable constant max backedge-taken count.
 ; CHECK-NEXT:  Loop %for.body: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
+; CHECK-NEXT:  Loop %for.body: Predicated symbolic max backedge-taken count is ((-21 + %N) /u 2)
+; CHECK-NEXT:   Predicates:
+; CHECK-NEXT:      {0,+,2}<%for.body> Added Flags: <nssw>
+; CHECK-NEXT:      Equal predicate: (zext i1 (true + (trunc i64 %N to i1)) to i64) == 0
 ;
 entry:
   br label %for.body
diff --git a/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll b/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
index 13e79a4a47b39c..f62c3c7f42ec4e 100644
--- a/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
+++ b/llvm/test/Transforms/LoopVectorize/opaque-ptr.ll
@@ -4,18 +4,80 @@
 define void @test_ptr_iv_no_inbounds(ptr %p1.start, ptr %p2.start, ptr %p1.end) {
 ; CHECK-LABEL: @test_ptr_iv_no_inbounds(
 ; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P1_START7:%.*]] = ptrtoint ptr [[P1_START:%.*]] to i64
+; CHECK-NEXT:    [[P1_END6:%.*]] = ptrtoint ptr [[P1_END:%.*]] to i64
+; CHECK-NEXT:    [[P1_START4:%.*]] = ptrtoint ptr [[P1_START]] to i64
+; CHECK-NEXT:    [[P1_END3:%.*]] = ptrtoint ptr [[P1_END]] to i64
+; CHECK-NEXT:    [[P1_START2:%.*]] = ptrtoint ptr [[P1_START]] to i64
+; CHECK-NEXT:    [[P1_END1:%.*]] = ptrtoint ptr [[P1_END]] to i64
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[P1_END6]], -4
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[P1_START7]]
+; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 1
+; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP3]], 2
+; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
+; CHECK:       vector.scevcheck:
+; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[P1_END1]] to i2
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[P1_START2]] to i2
+; CHECK-NEXT:    [[TMP6:%.*]] = sub i2 [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    [[TMP7:%.*]] = zext i2 [[TMP6]] to i64
+; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i64 [[TMP7]], 0
+; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]]
+; CHECK:       vector.memcheck:
+; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[P1_END3]], -4
+; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 [[TMP8]], [[P1_START4]]
+; CHECK-NEXT:    [[TMP10:%.*]] = lshr i64 [[TMP9]], 2
+; CHECK-NEXT:    [[TMP11:%.*]] = shl nuw i64 [[TMP10]], 2
+; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[TMP11]], 4
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP12]]
+; CHECK-NEXT:    [[SCEVGEP5:%.*]] = getelementptr i8, ptr [[P2_START:%.*]], i64 [[TMP12]]
+; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[P1_START]], [[SCEVGEP5]]
+; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[P2_START]], [[SCEVGEP]]
+; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
+; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
+; CHECK:       vector.ph:
+; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP3]], 2
+; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP3]], [[N_MOD_VF]]
+; CHECK-NEXT:    [[TMP13:%.*]] = mul i64 [[N_VEC]], 4
+; CHECK-NEXT:    [[IND_END:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP13]]
+; CHECK-NEXT:    [[TMP14:%.*]] = mul i64 [[N_VEC]], 4
+; CHECK-NEXT:    [[IND_END8:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP14]]
+; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
+; CHECK:       vector.body:
+; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 4
+; CHECK-NEXT:    [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 0
+; CHECK-NEXT:    [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[P1_START]], i64 [[TMP15]]
+; CHECK-NEXT:    [[OFFSET_IDX10:%.*]] = mul i64 [[INDEX]], 4
+; CHECK-NEXT:    [[TMP16:%.*]] = add i64 [[OFFSET_IDX10]], 0
+; CHECK-NEXT:    [[NEXT_GEP11:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP16]]
+; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr float, ptr [[NEXT_GEP]], i32 0
+; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP17]], align 4, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
+; CHECK-NEXT:    [[TMP18:%.*]] = getelementptr float, ptr [[NEXT_GEP11]], i32 0
+; CHECK-NEXT:    [[WIDE_LOAD12:%.*]] = load <2 x float>, ptr [[TMP18]], align 4, !alias.scope [[META3]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fadd <2 x float> [[WIDE_LOAD]], [[WIDE_LOAD12]]
+; CHECK-NEXT:    store <2 x float> [[TMP19]], ptr [[TMP17]], align 4, !alias.scope [[META0]], !noalias [[META3]]
+; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
+; CHECK-NEXT:    [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT:    br i1 [[TMP20]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
+; CHECK:       middle.block:
+; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[N_VEC]]
+; CHECK-NEXT:    br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK:       scalar.ph:
+; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi ptr [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[P1_START]], [[ENTRY:%.*]] ], [ [[P1_START]], [[VECTOR_SCEVCHECK]] ], [ [[P1_START]], [[VECTOR_MEMCHECK]] ]
+; CHECK-NEXT:    [[BC_RESUME_VAL9:%.*]] = phi ptr [ [[IND_END8]], [[MIDDLE_BLOCK]] ], [ [[P2_START]], [[ENTRY]] ], [ [[P2_START]], [[VECTOR_SCEVCHECK]] ], [ [[P2_START]], [[VECTOR_MEMCHECK]] ]
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK-NEXT:    [[P1:%.*]] = phi ptr [ [[P1_START:%.*]], [[ENTRY:%.*]] ], [ [[P1_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[P2:%.*]] = phi ptr [ [[P2_START:%.*]], [[ENTRY]] ], [ [[P2_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[P1:%.*]] = phi ptr [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[P1_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[P2:%.*]] = phi ptr [ [[BC_RESUME_VAL9]], [[SCALAR_PH]] ], [ [[P2_NEXT:%.*]], [[LOOP]] ]
 ; CHECK-NEXT:    [[P1_VAL:%.*]] = load float, ptr [[P1]], align 4
 ; CHECK-NEXT:    [[P2_VAL:%.*]] = load float, ptr [[P2]], align 4
 ; CHECK-NEXT:    [[SUM:%.*]] = fadd float [[P1_VAL]], [[P2_VAL]]
 ; CHECK-NEXT:    store float [[SUM]], ptr [[P1]], align 4
 ; CHECK-NEXT:    [[P1_NEXT]] = getelementptr float, ptr [[P1]], i64 1
 ; CHECK-NEXT:    [[P2_NEXT]] = getelementptr float, ptr [[P2]], i64 1
-; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P1_NEXT]], [[P1_END:%.*]]
-; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P1_NEXT]], [[P1_END]]
+; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP8:![0-9]+]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
@@ -80,14 +142,14 @@ define void @test_ptr_iv_with_inbounds(ptr %p1.start, ptr %p2.start, ptr %p1.end
 ; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[OFFSET_IDX8]], 0
 ; CHECK-NEXT:    [[NEXT_GEP9:%.*]] = getelementptr i8, ptr [[P2_START]], i64 [[TMP12]]
 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr float, ptr [[NEXT_GEP]], i32 0
-; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP13]], align 4, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
+; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x float>, ptr [[TMP13]], align 4, !alias.scope [[META9:![0-9]+]], !noalias [[META12:![0-9]+]]
 ; CHECK-NEXT:    [[TMP14:%...
[truncated]

This can help in cases where pointer alignment info is missing, e.g.
llvm#108210

The predicate is formed for the complex expression that's passed to
SolveLinEquationWithOverflow and the checks could probably be pushed
closer to the root nodes, which in some cases may be cheaper to check.
@fhahn fhahn force-pushed the scev-align-predicate branch from 3551969 to c91b942 Compare September 15, 2024 21:11
Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a nice fix!

; exit count for the loop.inc block here, in the same way as
; ptr_induction_eq_1. The problem seems to be in howFarToZero when the
; ControlsOnlyExit is set to false.
; %a and %b may not have the same alignment, so the loop may only via the early
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/so the loop may only via/so the loop may only exit via/

// Avoid adding a predicate that is known to be false.
if (SE.isKnownPredicate(CmpInst::ICMP_NE, URem, Zero))
return SE.getCouldNotCompute();
Predicates->insert(SE.getEqualPredicate(URem, Zero));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thinking in terms of compile-time here - can you get the equivalent result if you first compute SE.getEqualPredicate(URem, Zero) and then test if the answer is constant-false? I don't know if isKnownPredicate is expensive or not and whether or not we care.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the terminology is a bit confusing, the predicate in isKnownPredicate refers to condition to check for the arguments, while predicate in getEqualPredicate refers to a SCEVPredicate (used by PredicateScalarEvolution) and those cannot be used by the isKnownPredicate helpers AFAIK

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK that's fair enough! Thanks for the explanation

Copy link
Collaborator

@preames preames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

LGTM w/optional follow up.

@@ -10137,8 +10140,17 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
//
// B is divisible by D if and only if the multiplicity of prime factor 2 for B
// is not less than multiplicity of this prime factor for D.
if (SE.getMinTrailingZeros(B) < Mult2)
return SE.getCouldNotCompute();
if (SE.getMinTrailingZeros(B) < Mult2) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we maybe try to prove that (urem B, A) == 0 before resorting to the predicate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC that check shouldn't be true, otherwise we are missing some logic in getMinTrailingZeros? Added an assert that the check isn't true.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the reframing of urem (B, 1 << Mult2) == 0, I agree with your comment, but I think we could reasonable see divergence with the original urem(B,A) check. Those are just different enough.

My suggestion is basically, can we prove the original fact without using the trailing bits proof strategy? Said differently. what if D = gcd(A, N) is something like 3^M?

Hm, though now I see that the multiplicative inverse code below would need updated too. I'd missed that originally.

(Totally fine to move forward here, this is purely a possible followup.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stand corrected, the assertion actually uncovered a case where getMinTrailingZeros returns a worse result and I think catching this in getMinTrailingZeros would require matching a specific pattern (https://alive2.llvm.org/ce/z/t3A5X2)

I updated the code to check if the URem is zero if the trailing bits check failed, as we need to build the expression there already. Test is in llvm/test/Analysis/ScalarEvolution/trip-count-urem.ll

if (!Predicates)
return SE.getCouldNotCompute();
// Try to add a predicate ensuring B is a multiple of A.
const SCEV *URem = SE.getURemExpr(B, SE.getConstant(A));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why B % A, and not B % (1 << Mult2)?

I don't think this actually impacts any of the existing testcases; probably worth adding a few so we have coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated thanks. Test has been added in 28439a1

fhahn added a commit that referenced this pull request Sep 26, 2024
return SE.getCouldNotCompute();
// Try to add a predicate ensuring B is a multiple of 1 << Mult2.
const SCEV *URem =
SE.getURemExpr(B, SE.getConstant(B->getType(), 1 << Mult2));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Mult2 guaranteed less than 32? Don't see anything enforcing as much. Maybe APInt::getOneBitSet(BW, Mult2)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated!

@@ -10137,8 +10140,17 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
//
// B is divisible by D if and only if the multiplicity of prime factor 2 for B
// is not less than multiplicity of this prime factor for D.
if (SE.getMinTrailingZeros(B) < Mult2)
return SE.getCouldNotCompute();
if (SE.getMinTrailingZeros(B) < Mult2) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the reframing of urem (B, 1 << Mult2) == 0, I agree with your comment, but I think we could reasonable see divergence with the original urem(B,A) check. Those are just different enough.

My suggestion is basically, can we prove the original fact without using the trailing bits proof strategy? Said differently. what if D = gcd(A, N) is something like 3^M?

Hm, though now I see that the multiplicative inverse code below would need updated too. I'd missed that originally.

(Totally fine to move forward here, this is purely a possible followup.)

fhahn added a commit that referenced this pull request Sep 27, 2024
Also adds additional test coverage in
Analysis/ScalarEvolution/trip-count-urem.ll

Extra test coverage is for #108777.
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
Also adds additional test coverage in
Analysis/ScalarEvolution/trip-count-urem.ll

Extra test coverage is for llvm#108777.
Test needs a few less checks.
@fhahn fhahn merged commit 2f7ccaf into llvm:main Sep 28, 2024
6 of 8 checks passed
@fhahn fhahn deleted the scev-align-predicate branch September 28, 2024 13:20
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 28, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-aarch64-linux running on sanitizer-buildbot8 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/4460

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
+ [[ -march=armv8-a =~ -m32 ]]
+ FLAGS+=' -fPIC -flto -Oz -g0 -DNDEBUG -target aarch64-unknown-linux-gnu -Wno-unused-command-line-argument'
+ FLAGS+=' -include /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/../sanitizer_redefine_builtins.h -DSANITIZER_COMMON_REDEFINE_BUILTINS_IN_STD -Wno-language-extension-token'
+ LINKFLAGS='-fuse-ld=lld -target aarch64-unknown-linux-gnu'
+ [[ ! -d /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib ]]
+ [[ -z '' ]]
+ git clone https://github.com/madler/zlib /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib
Cloning into '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib'...
fatal: unable to access 'https://github.com/madler/zlib/': Recv failure: Connection reset by peer
[1524/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_stackdepot.cpp.o
FAILED: compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o 
cd /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64 && FLAGS=-march=armv8-a CLANG=/home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o
[1526/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/ostream.cpp.o
[1527/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibcNoHooks.aarch64.dir/sanitizer_stoptheworld_linux_libcdep.cpp.o
[1528/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_markup.cpp.o
[1529/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_mac.cpp.o
[1530/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/fstream.cpp.o
[1531/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_preinit.cpp.o
[1532/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/regex.cpp.o
[1533/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibcNoHooks.aarch64.dir/sanitizer_linux_libcdep.cpp.o
[1534/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan_cxx.aarch64.dir/ubsan_type_hash.cpp.o
[1535/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_fuchsia.cpp.o
[1536/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_flags.cpp.o
[1537/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_report.cpp.o
[1538/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_value.cpp.o
[1539/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_linux.cpp.o
[1540/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan.cpp.o
[1541/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_linux.cpp.o
[1542/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_posix_libcdep.cpp.o
[1543/2002] Building CXX object compiler-rt/lib/stats/CMakeFiles/clang_rt.stats-aarch64.dir/stats.cpp.o
[1544/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_init.cpp.o
[1545/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_libcdep.cpp.o
[1546/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/filesystem/path.cpp.o
[1547/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/random_shuffle.cpp.o
[1548/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.aarch64.dir/sanitizer_thread_registry.cpp.o
[1549/2002] Building CXX object libcxx/src/CMakeFiles/cxx_shared.dir/filesystem/directory_iterator.cpp.o
[1550/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_monitor.cpp.o
[1551/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_posix.cpp.o
[1552/2002] Building CXX object libcxx/src/CMakeFiles/cxx_experimental.dir/experimental/chrono_exception.cpp.o
[1553/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_stack_store.cpp.o
[1554/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan_cxx.aarch64.dir/ubsan_handlers_cxx.cpp.o
[1555/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_diag.cpp.o
[1556/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_thread.cpp.o
[1557/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/algorithm.cpp.o
[1558/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/strstream.cpp.o
[1559/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_interceptors.cpp.o
[1560/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common.cpp.o
[1561/2002] Building CXX object libcxx/src/CMakeFiles/cxx_experimental.dir/experimental/tzdb_list.cpp.o
[1562/2002] Building CXX object libcxx/src/CMakeFiles/cxx_shared.dir/filesystem/operations.cpp.o
Step 8 (build compiler-rt symbolizer) failure: build compiler-rt symbolizer (failure)
...
+ [[ -march=armv8-a =~ -m32 ]]
+ FLAGS+=' -fPIC -flto -Oz -g0 -DNDEBUG -target aarch64-unknown-linux-gnu -Wno-unused-command-line-argument'
+ FLAGS+=' -include /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/../sanitizer_redefine_builtins.h -DSANITIZER_COMMON_REDEFINE_BUILTINS_IN_STD -Wno-language-extension-token'
+ LINKFLAGS='-fuse-ld=lld -target aarch64-unknown-linux-gnu'
+ [[ ! -d /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib ]]
+ [[ -z '' ]]
+ git clone https://github.com/madler/zlib /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib
Cloning into '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib'...
fatal: unable to access 'https://github.com/madler/zlib/': Recv failure: Connection reset by peer
[1524/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_stackdepot.cpp.o
FAILED: compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o 
cd /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64 && FLAGS=-march=armv8-a CLANG=/home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o
[1526/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/ostream.cpp.o
[1527/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibcNoHooks.aarch64.dir/sanitizer_stoptheworld_linux_libcdep.cpp.o
[1528/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_markup.cpp.o
[1529/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_mac.cpp.o
[1530/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/fstream.cpp.o
[1531/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_preinit.cpp.o
[1532/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/regex.cpp.o
[1533/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibcNoHooks.aarch64.dir/sanitizer_linux_libcdep.cpp.o
[1534/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan_cxx.aarch64.dir/ubsan_type_hash.cpp.o
[1535/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_fuchsia.cpp.o
[1536/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_flags.cpp.o
[1537/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_report.cpp.o
[1538/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_value.cpp.o
[1539/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_linux.cpp.o
[1540/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan.cpp.o
[1541/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common_linux.cpp.o
[1542/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_posix_libcdep.cpp.o
[1543/2002] Building CXX object compiler-rt/lib/stats/CMakeFiles/clang_rt.stats-aarch64.dir/stats.cpp.o
[1544/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_init.cpp.o
[1545/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_symbolizer_libcdep.cpp.o
[1546/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/filesystem/path.cpp.o
[1547/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/random_shuffle.cpp.o
[1548/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.aarch64.dir/sanitizer_thread_registry.cpp.o
[1549/2002] Building CXX object libcxx/src/CMakeFiles/cxx_shared.dir/filesystem/directory_iterator.cpp.o
[1550/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_monitor.cpp.o
[1551/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_posix.cpp.o
[1552/2002] Building CXX object libcxx/src/CMakeFiles/cxx_experimental.dir/experimental/chrono_exception.cpp.o
[1553/2002] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.aarch64.dir/sanitizer_stack_store.cpp.o
[1554/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan_cxx.aarch64.dir/ubsan_handlers_cxx.cpp.o
[1555/2002] Building CXX object compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.aarch64.dir/ubsan_diag.cpp.o
[1556/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_thread.cpp.o
[1557/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/algorithm.cpp.o
[1558/2002] Building CXX object libcxx/src/CMakeFiles/cxx_static.dir/strstream.cpp.o
[1559/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/clang_rt.lsan-aarch64.dir/lsan_interceptors.cpp.o
[1560/2002] Building CXX object compiler-rt/lib/lsan/CMakeFiles/RTLSanCommon.aarch64.dir/lsan_common.cpp.o
[1561/2002] Building CXX object libcxx/src/CMakeFiles/cxx_experimental.dir/experimental/tzdb_list.cpp.o
[1562/2002] Building CXX object libcxx/src/CMakeFiles/cxx_shared.dir/filesystem/operations.cpp.o
Step 9 (test compiler-rt symbolizer) failure: test compiler-rt symbolizer (failure)
...
+ [[ -march=armv8-a =~ -m32 ]]
+ FLAGS+=' -fPIC -flto -Oz -g0 -DNDEBUG -target aarch64-unknown-linux-gnu -Wno-unused-command-line-argument'
+ FLAGS+=' -include /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/../sanitizer_redefine_builtins.h -DSANITIZER_COMMON_REDEFINE_BUILTINS_IN_STD -Wno-language-extension-token'
+ LINKFLAGS='-fuse-ld=lld -target aarch64-unknown-linux-gnu'
+ [[ ! -d /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib ]]
+ [[ -z '' ]]
+ git clone https://github.com/madler/zlib /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib
Cloning into '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64/symbolizer/zlib'...
fatal: unable to access 'https://github.com/madler/zlib/': gnutls_handshake() failed: The TLS connection was non-properly terminated.
[363/583] Linking CXX static library compiler-rt/lib/scudo/standalone/tests/libRTScudoCxxUnitTest.aarch64.a
FAILED: compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o 
cd /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64 && FLAGS=-march=armv8-a CLANG=/home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/sanitizer_common/symbolizer/RTSanitizerCommonSymbolizerInternal.aarch64.o
[365/583] Building CXX object compiler-rt/lib/scudo/standalone/CMakeFiles/clang_rt.scudo_standalone-aarch64.dir/wrappers_c.cpp.o
[366/583] Building CXX object compiler-rt/lib/scudo/standalone/CMakeFiles/clang_rt.scudo_standalone-dynamic-aarch64.dir/wrappers_c.cpp.o
[367/583] Building CXX object compiler-rt/lib/orc/CMakeFiles/RTOrc.aarch64.dir/elfnix_platform.cpp.o
[368/583] Generating RtsanTestObjects_FileOffset64.gmock-all.cc.aarch64.o
[369/583] Generating RtsanTestObjects_FileOffset64.rtsan_test_functional.cpp.aarch64.o
[370/583] Generating RtsanTestObjects.gmock-all.cc.aarch64.o
[371/583] Generating RtsanTestObjects.rtsan_test_functional.cpp.aarch64.o
[372/583] Generating RtsanTestObjects_FileOffset64.rtsan_test_interceptors.cpp.aarch64.o
[373/583] Building CXX object compiler-rt/lib/tsan/rtl/CMakeFiles/clang_rt.tsan-dynamic-aarch64.dir/tsan_interceptors_posix.cpp.o
[374/583] Building CXX object compiler-rt/lib/tsan/rtl/CMakeFiles/clang_rt.tsan-aarch64.dir/tsan_interceptors_posix.cpp.o
[375/583] Generating RtsanTestObjects.rtsan_test_interceptors.cpp.aarch64.o
[376/583] Building CXX object compiler-rt/lib/msan/CMakeFiles/clang_rt.msan-aarch64.dir/msan_interceptors.cpp.o
[377/583] Building CXX object compiler-rt/lib/asan/CMakeFiles/RTAsan.aarch64.dir/asan_interceptors.cpp.o
[378/583] Building CXX object compiler-rt/lib/asan/CMakeFiles/RTAsan_dynamic.aarch64.dir/asan_interceptors.cpp.o
[379/583] Generating RtsanTestObjects.gtest-all.cc.aarch64.o
[380/583] Generating RtsanTestObjects_FileOffset64.gtest-all.cc.aarch64.o
ninja: build stopped: subcommand failed.
FAILED: runtimes/CMakeFiles/check-compiler-rt /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/CMakeFiles/check-compiler-rt 
cd /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins && /usr/bin/cmake --build /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/ --target check-compiler-rt --config Release
ninja: build stopped: subcommand failed.

How to reproduce locally: https://github.com/google/sanitizers/wiki/SanitizerBotReproduceBuild

@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 28, 2024

LLVM Buildbot has detected a new failure on builder reverse-iteration running on hexagon-build-03 while building llvm at step 6 "check_all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/110/builds/1494

Here is the relevant piece of the build log for the reference
Step 6 (check_all) failure: test (failure)
******************** TEST 'LLVM :: Analysis/ScalarEvolution/ne-overflow.ll' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.obj/bin/opt /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll -passes='print<scalar-evolution>' -scalar-evolution-classify-expressions=0 -disable-output 2>&1 | /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.obj/bin/FileCheck /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
+ /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.obj/bin/opt /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll '-passes=print<scalar-evolution>' -scalar-evolution-classify-expressions=0 -disable-output
+ /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.obj/bin/FileCheck /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll
/local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll:355:15: error: CHECK-NEXT: is not on the line after the previous match
; CHECK-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
              ^
<stdin>:148:2: note: 'next' match was here
 {0,+,2}<%for.body> Added Flags: <nssw>
 ^
<stdin>:146:13: note: previous match ended here
 Predicates:
            ^
<stdin>:147:1: note: non-matching line after previous match is here
 {0,+,2}<%for.body> Added Flags: <nusw>
^

Input file: <stdin>
Check file: /local/mnt/workspace/bots/hexagon-build-03/reverse-iteration/llvm.src/llvm/test/Analysis/ScalarEvolution/ne-overflow.ll

-dump-input=help explains the following input dump.

Input was:
<<<<<<
          .
          .
          .
        143: Loop %for.body: Unpredictable constant max backedge-taken count.  
        144: Loop %for.body: Unpredictable symbolic max backedge-taken count.  
        145: Loop %for.body: Predicated backedge-taken count is (%N /u 2) 
        146:  Predicates: 
        147:  {0,+,2}<%for.body> Added Flags: <nusw> 
        148:  {0,+,2}<%for.body> Added Flags: <nssw> 
next:355      !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  error: match on wrong line
        149:  Equal predicate: (zext i1 (trunc i64 %N to i1) to i64) == 0 
        150: Loop %for.body: Predicated constant max backedge-taken count is i64 9223372036854775807 
        151:  Predicates: 
        152:  {0,+,2}<%for.body> Added Flags: <nusw> 
        153:  {0,+,2}<%for.body> Added Flags: <nssw> 
          .
          .
          .
>>>>>>

--

...

@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 28, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux-qemu running on sanitizer-buildbot4 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/139/builds/4340

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure) (timed out)
...
[    6.886216] pci_bus 0000:00: root bus resource [bus 00-ff]
[    6.894315] pci 0000:00:00.0: [8086:29c0] type 00 class 0x060000 conventional PCI endpoint
[    6.908216] pci 0000:00:01.0: [1234:1111] type 00 class 0x030000 conventional PCI endpoint
[    6.909216] pci 0000:00:01.0: BAR 0 [mem 0xfd000000-0xfdffffff pref]
[    6.911311] pci 0000:00:01.0: BAR 2 [mem 0xfebf0000-0xfebf0fff]
[    6.915216] pci 0000:00:01.0: ROM [mem 0xfebe0000-0xfebeffff pref]
[    6.915216] pci 0000:00:01.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
[    6.915216] pci 0000:00:02.0: [8086:100e] type 00 class 0x020000 conventional PCI endpoint
[    6.915216] pci 0000:00:02.0: BAR 0 [mem 0xfebc0000-0xfebdffff]
[    6.916320] pci 0000:00:02.0: BAR 1 [io  0xc000-0xc03f]
command timed out: 1200 seconds without output running [b'python', b'../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py'], attempting to kill
process killed by signal 9
program finished with exit code -1
elapsedTime=3686.807030
Step 29 (start LAM QEMU) failure: start LAM QEMU (failure)
...
[    6.671191] thermal_sys: Registered thermal governor 'user_space'
[    6.676923] cpuidle: using governor menu
[    6.688216] PCI: ECAM [mem 0xb0000000-0xbfffffff] (base 0xb0000000) for domain 0000 [bus 00-ff]
[    6.690729] PCI: ECAM [mem 0xb0000000-0xbfffffff] reserved as E820 entry
[    6.692216] PCI: Using configuration type 1 for base access
[    6.693216] mtrr: your CPUs had inconsistent fixed MTRR settings
[    6.693312] mtrr: your CPUs had inconsistent variable MTRR settings
[    6.693662] mtrr: your CPUs had inconsistent MTRRdefType settings
[    6.693960] mtrr: probably your BIOS does not setup all CPUs.
[    6.694216] mtrr: corrected configuration.
[    6.700216] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    6.719811] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
[    6.720360] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
[    6.734216] ACPI: Added _OSI(Module Device)
[    6.734216] ACPI: Added _OSI(Processor Device)
[    6.734216] ACPI: Added _OSI(3.0 _SCP Extensions)
[    6.734216] ACPI: Added _OSI(Processor Aggregator Device)
[    6.771216] ACPI: 1 ACPI AML tables successfully acquired and loaded
[    6.792216] ACPI: Interpreter enabled
[    6.793216] ACPI: PM: (supports S0 S3 S4 S5)
[    6.793216] ACPI: Using IOAPIC for interrupt routing
[    6.797423] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    6.798157] PCI: Using E820 reservations for host bridge windows
[    6.799474] ACPI: Enabled 2 GPEs in block 00 to 3F
[    6.872537] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    6.876216] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
[    6.879216] acpi PNP0A08:00: _OSC: platform does not support [LTR]
[    6.879601] acpi PNP0A08:00: _OSC: OS now controls [PME PCIeCapability]
[    6.885351] PCI host bridge to bus 0000:00
[    6.886122] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
[    6.886216] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    6.886216] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
[    6.886216] pci_bus 0000:00: root bus resource [mem 0x80000000-0xafffffff window]
[    6.886216] pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window]
[    6.886216] pci_bus 0000:00: root bus resource [mem 0x480000000-0xc7fffffff window]
[    6.886216] pci_bus 0000:00: root bus resource [bus 00-ff]
[    6.894315] pci 0000:00:00.0: [8086:29c0] type 00 class 0x060000 conventional PCI endpoint
[    6.908216] pci 0000:00:01.0: [1234:1111] type 00 class 0x030000 conventional PCI endpoint
[    6.909216] pci 0000:00:01.0: BAR 0 [mem 0xfd000000-0xfdffffff pref]
[    6.911311] pci 0000:00:01.0: BAR 2 [mem 0xfebf0000-0xfebf0fff]
[    6.915216] pci 0000:00:01.0: ROM [mem 0xfebe0000-0xfebeffff pref]
[    6.915216] pci 0000:00:01.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
[    6.915216] pci 0000:00:02.0: [8086:100e] type 00 class 0x020000 conventional PCI endpoint
[    6.915216] pci 0000:00:02.0: BAR 0 [mem 0xfebc0000-0xfebdffff]
[    6.916320] pci 0000:00:02.0: BAR 1 [io  0xc000-0xc03f]

command timed out: 1200 seconds without output running [b'python', b'../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py'], attempting to kill
process killed by signal 9
program finished with exit code -1
elapsedTime=3686.807030

fhahn added a commit that referenced this pull request Sep 28, 2024
Store predicates in ExitLimit and ExitNotTaken in a SmallVector instead
of a SmallPtrSet. This guarantees the predicates can be iterated on in a
predictable manner. This ensures the predicates can be printed and
generated in a predictable order.

This shifts de-duplication of predicates to construction time for
ExitLimit. ExitNotTaken just takes predicates from ExitLimit, so they
should also be free of duplicates.

This was exposed by 2f7ccaf
(#108777).

Should fix https://lab.llvm.org/buildbot/#/builders/110/builds/1494.
@fhahn
Copy link
Contributor Author

fhahn commented Sep 28, 2024

There was a genuine reverse-iteration failure due to predicates in ExitLimit and ExitNotTaken were stored in SmallPtrSet. I pushed a fix to store them in SmallVectors, doing de-duplication when constructing ExitLimit: 6022a3a

puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Sep 30, 2024
Also adds additional test coverage in
Analysis/ScalarEvolution/trip-count-urem.ll

Extra test coverage is for llvm/llvm-project#108777.
puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Sep 30, 2024
…108777)

This can help in cases where pointer alignment info is missing, e.g.
llvm/llvm-project#108210

The predicate is formed for the complex expression that's passed to
SolveLinEquationWithOverflow and the checks could probably be pushed
closer to the root nodes, which in some cases may be cheaper to check.


PR: llvm/llvm-project#108777
puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Sep 30, 2024
Store predicates in ExitLimit and ExitNotTaken in a SmallVector instead
of a SmallPtrSet. This guarantees the predicates can be iterated on in a
predictable manner. This ensures the predicates can be printed and
generated in a predictable order.

This shifts de-duplication of predicates to construction time for
ExitLimit. ExitNotTaken just takes predicates from ExitLimit, so they
should also be free of duplicates.

This was exposed by 2f7ccaf4a8565628a4c7d2b5a49bb45478940be6
(llvm/llvm-project#108777).

Should fix https://lab.llvm.org/buildbot/#/builders/110/builds/1494.
puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Oct 2, 2024
Also adds additional test coverage in
Analysis/ScalarEvolution/trip-count-urem.ll

Extra test coverage is for llvm/llvm-project#108777.
puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Oct 2, 2024
…108777)

This can help in cases where pointer alignment info is missing, e.g.
llvm/llvm-project#108210

The predicate is formed for the complex expression that's passed to
SolveLinEquationWithOverflow and the checks could probably be pushed
closer to the root nodes, which in some cases may be cheaper to check.


PR: llvm/llvm-project#108777
puja2196 pushed a commit to puja2196/LLVM-tutorial that referenced this pull request Oct 2, 2024
Store predicates in ExitLimit and ExitNotTaken in a SmallVector instead
of a SmallPtrSet. This guarantees the predicates can be iterated on in a
predictable manner. This ensures the predicates can be printed and
generated in a predictable order.

This shifts de-duplication of predicates to construction time for
ExitLimit. ExitNotTaken just takes predicates from ExitLimit, so they
should also be free of duplicates.

This was exposed by 2f7ccaf4a8565628a4c7d2b5a49bb45478940be6
(llvm/llvm-project#108777).

Should fix https://lab.llvm.org/buildbot/#/builders/110/builds/1494.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants