Skip to content
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

[SCEV] Simplify SCEVExpr for PHI to SCEV for operand if operands are identical #115945

Merged
merged 7 commits into from
Dec 6, 2024

Conversation

akshayrdeodhar
Copy link
Contributor

Helps SCEV analyze some special phi nodes, allowing the computation of loop trip count in cases like the following:

https://godbolt.org/z/xGs1d81TW

@llvmbot
Copy link
Member

llvmbot commented Nov 12, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Akshay Deodhar (akshayrdeodhar)

Changes

Helps SCEV analyze some special phi nodes, allowing the computation of loop trip count in cases like the following:

https://godbolt.org/z/xGs1d81TW


Full diff: https://github.com/llvm/llvm-project/pull/115945.diff

3 Files Affected:

  • (modified) llvm/include/llvm/Analysis/ScalarEvolution.h (+4)
  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+34)
  • (added) llvm/test/Analysis/ScalarEvolution/trip-count16.ll (+46)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 4b8cb3a39a86db..86f4cb92152836 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1761,6 +1761,10 @@ class ScalarEvolution {
   /// V.
   const SCEV *getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops);
 
+  /// Returns SCEV for the first operand of a phi if all phi operands have
+  /// identical opcodes and operands
+  const SCEV *createNodeForPHIWithIdenticalOperands(PHINode *PN);
+
   /// Provide the special handling we need to analyze PHI SCEVs.
   const SCEV *createNodeForPHI(PHINode *PN);
 
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b10811133770e1..3480dda484f333 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6019,6 +6019,37 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
   return nullptr;
 }
 
+// Returns SCEV for the first operand of a phi if all phi operands have
+// identical opcodes and operands
+// eg.
+// a: %add = %a + %b
+//    br %c
+// b: %add1 = %a + %b
+//    br %c
+// c: %phi = phi [%add, a], [%add1, b]
+// scev(%phi) => scev(%add)
+const SCEV *
+ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
+  BinaryOperator *CommonInst = nullptr;
+  for (Value *Incoming : PN->incoming_values()) {
+    BinaryOperator *IncomingInst = dyn_cast<BinaryOperator>(Incoming);
+    if (CommonInst) {
+      if (!(IncomingInst && CommonInst->isIdenticalTo(IncomingInst))) {
+        // Not identical, give up
+        CommonInst = nullptr;
+        break;
+      }
+    } else if (IncomingInst) {
+      // Remember binary operator
+      CommonInst = IncomingInst;
+    } else {
+      // Not a binary operator, give up
+      return nullptr;
+    }
+  }
+  return CommonInst ? getSCEV(CommonInst) : nullptr;
+}
+
 const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
   if (const SCEV *S = createAddRecFromPHI(PN))
     return S;
@@ -6030,6 +6061,9 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
                /*UseInstrInfo=*/true, /*CanUseUndef=*/false}))
     return getSCEV(V);
 
+  if (const SCEV *S = createNodeForPHIWithIdenticalOperands(PN))
+    return S;
+
   if (const SCEV *S = createNodeFromSelectLikePHI(PN))
     return S;
 
diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count16.ll b/llvm/test/Analysis/ScalarEvolution/trip-count16.ll
new file mode 100644
index 00000000000000..2b267edb2438f9
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/trip-count16.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck %s
+define void @test(ptr %x, ptr %y) {
+; CHECK-LABEL: 'test'
+; CHECK-NEXT:  Classifying expressions for: @test
+; CHECK-NEXT:    %v1.0 = phi i32 [ 0, %entry ], [ %k.0, %if.end ]
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%for.cond> U: [0,7) S: [0,7) Exits: 6 LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT:    %add = add nsw i32 %v1.0, 1
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%for.cond> U: [1,8) S: [1,8) Exits: 7 LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT:    %add6 = add nsw i32 %v1.0, 1
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%for.cond> U: [1,8) S: [1,8) Exits: 7 LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT:    %k.0 = phi i32 [ %add, %if.then ], [ %add6, %if.else ]
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%for.cond> U: [1,8) S: [1,8) Exits: 7 LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT:  Determining loop execution counts for: @test
+; CHECK-NEXT:  Loop %for.cond: backedge-taken count is i32 6
+; CHECK-NEXT:  Loop %for.cond: constant max backedge-taken count is i32 6
+; CHECK-NEXT:  Loop %for.cond: symbolic max backedge-taken count is i32 6
+; CHECK-NEXT:  Loop %for.cond: Trip multiple is 7
+;
+entry:
+  br label %for.cond
+
+for.cond:                                                ; preds = %6, %0
+  %v1.0 = phi i32 [ 0, %entry ], [ %k.0, %if.end ]
+  %cmp = icmp slt i32 %v1.0, 6
+  br i1 %cmp, label %for.body, label %exit
+
+for.body:                                                ; preds = %1
+  %cmp3 = icmp slt i32 %v1.0, 2
+  br i1 %cmp3, label %if.then, label %if.else
+
+if.then:                                                ; preds = %2
+  %add = add nsw i32 %v1.0, 1
+  br label %if.end
+
+if.else:                                                ; preds = %2
+  %add6 = add nsw i32 %v1.0, 1
+  br label %if.end
+
+if.end:                                                ; preds = %4, %3
+  %k.0 = phi i32 [ %add, %if.then ], [ %add6, %if.else ]
+  br label %for.cond
+
+exit:                                                ; preds = %5
+  ret void
+}

@akshayrdeodhar akshayrdeodhar requested review from fhahn, nikic and dtcxzyw and removed request for nikic November 12, 2024 21:56
@akshayrdeodhar
Copy link
Contributor Author

CC: @fiigii

llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
for (Value *Incoming : PN->incoming_values()) {
BinaryOperator *IncomingInst = dyn_cast<BinaryOperator>(Incoming);
if (CommonInst) {
if (!(IncomingInst && CommonInst->isIdenticalTo(IncomingInst))) {
Copy link
Member

Choose a reason for hiding this comment

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

Should we check that all incoming instructions belong to the same loop?

Copy link
Contributor Author

@akshayrdeodhar akshayrdeodhar Nov 15, 2024

Choose a reason for hiding this comment

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

If the operands of the phi are identical, then the simplification is correct regardless of whether instructions belong to the same loop- I think there's no advantage to special-casing this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ping?

@akshayrdeodhar akshayrdeodhar marked this pull request as ready for review November 18, 2024 20:23
@akshayrdeodhar
Copy link
Contributor Author

Erroneously pushed a partial rebase, reviewers were added due to merge conflicts. Have removed them now, and have restored the PR to be based off an older version of main.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

This looks somewhat iffy -- SCEV really shouldn't be going this kind of instruction comparison, that's the job of instruction hoisting. Of course, we have some weaknesses that prevent it from working in your example. I believe #78615 would fix it, but it's a tricky change. If this is common/important in practice, working around the issue in SCEV is an option.

llvm/include/llvm/Analysis/ScalarEvolution.h Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/test/Analysis/ScalarEvolution/trip-count16.ll Outdated Show resolved Hide resolved
return nullptr;
}
}
return CommonInst ? getSCEV(CommonInst) : nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks dangerous to me. Even if the instructions are the same, I think that SCEV would be allowed to use context-sensitive reasoning when constructing the SCEV node. It would be safer to call getSCEV for each incoming value in a second loop and make sure they're all the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using a single loop with calls to getSCEV.

Copy link
Contributor

Choose a reason for hiding this comment

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

I expect that you do need both loops -- not for correctness, but as a profitability heuristic. Computing SCEVs is expensive, and always recursing through phis would likely add significant cost.

I tried to confirm this but the stage2 build crashes (https://llvm-compile-time-tracker.com/show_error.php?commit=a4e3a0e648d7a3664ca6269e846abf2e6ddcdb08). I didn't investigate, but it might be that the recursion causes a stack overflow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Restored the original loop, and added an all_of check for SCEV exprs of the incoming values being identical.

@akshayrdeodhar
Copy link
Contributor Author

Thanks for the suggestions! Won't have internet access for 2 days, will address the comments on Monday. This does affect some real workloads, which is why I wanted to work around this in SCEV.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

Compile-time: https://llvm-compile-time-tracker.com/compare.php?from=29062329f3cf0ac8f1ae626e758ca64f82294fbf&to=b49b86076b0cfe3449462cc8e81fd2e450d0088d&stat=instructions%3Au There is a large impact on kimwy.cc, but it also has large code size changes, so probably second order effects.

llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
llvm/lib/Analysis/ScalarEvolution.cpp Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Nov 27, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM, but I'd like a second opinion on this one.

@akshayrdeodhar
Copy link
Contributor Author

CC: @dtcxzyw @fhahn for the second opinion?

@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 2, 2024

Not sure if this regression matters...

Regression (reduced from https://github.com/dtcxzyw/llvm-opt-benchmark/pull/1696/files#r1843118408):

; bin/opt -O3 reduced.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

declare i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32)

define i32 @_ZN6icu_7512_GLOBAL__N_17toUpperEijPDsiPKDsP12UCaseContextiPNS_5EditsER10UErrorCode(ptr nocapture readonly %src, i32 %srcLength) local_unnamed_addr {
entry:
  br label %while.cond.outer

while.cond.outer:                                 ; preds = %if.end13, %entry
  %srcIndex.0.ph = phi i32 [ %inc, %if.end13 ], [ 0, %entry ]
  %destIndex.0.ph = phi i32 [ 1, %if.end13 ], [ 0, %entry ]
  %cmp12 = icmp slt i32 %srcIndex.0.ph, %srcLength
  br i1 %cmp12, label %while.body, label %common.ret

while.body:                                       ; preds = %while.cond.outer, %while.cond.backedge
  %srcIndex.03 = phi i32 [ %srcIndex.0.be, %while.cond.backedge ], [ %srcIndex.0.ph, %while.cond.outer ]
  %idxprom = sext i32 %srcIndex.03 to i64
  %arrayidx = getelementptr i16, ptr %src, i64 %idxprom
  %0 = load i16, ptr %arrayidx, align 2
  %cmp2 = icmp eq i16 %0, 0
  br i1 %cmp2, label %if.then3, label %if.else15

if.then3:                                         ; preds = %while.body
  %1 = load i8, ptr %src, align 1
  %inc = add nsw i32 %srcIndex.03, 1
  %cmp11 = icmp eq i8 %1, 0
  br i1 %cmp11, label %while.cond.backedge, label %if.end13

while.cond.backedge:                              ; preds = %if.then3, %if.else15
  %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ]
  %cmp1 = icmp slt i32 %srcIndex.0.be, %srcLength
  br i1 %cmp1, label %while.body, label %common.ret

if.end13:                                         ; preds = %if.then3
  %call50 = tail call i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32 %destIndex.0.ph)
  %cmp58 = icmp slt i32 %call50, 0
  br i1 %cmp58, label %common.ret, label %while.cond.outer

if.else15:                                        ; preds = %while.body
  %inc33 = add nsw i32 %srcIndex.03, 1
  br label %while.cond.backedge

common.ret:                                       ; preds = %if.end13, %while.cond.outer, %while.cond.backedge
  ret i32 0
}

Before (22417ec):

; ModuleID = 'reduced.ll'
source_filename = "reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

declare i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32) local_unnamed_addr

define noundef i32 @_ZN6icu_7512_GLOBAL__N_17toUpperEijPDsiPKDsP12UCaseContextiPNS_5EditsER10UErrorCode(ptr nocapture readonly %src, i32 %srcLength) local_unnamed_addr {
entry:
  br label %while.cond.outer

while.cond.outer:                                 ; preds = %if.end13, %entry
  %srcIndex.0.ph = phi i32 [ %inc, %if.end13 ], [ 0, %entry ]
  %destIndex.0.ph = phi i32 [ 1, %if.end13 ], [ 0, %entry ]
  %cmp12 = icmp slt i32 %srcIndex.0.ph, %srcLength
  br i1 %cmp12, label %while.body, label %common.ret

while.body:                                       ; preds = %while.cond.outer, %while.cond.backedge
  %srcIndex.03 = phi i32 [ %srcIndex.0.be, %while.cond.backedge ], [ %srcIndex.0.ph, %while.cond.outer ]
  %idxprom = sext i32 %srcIndex.03 to i64
  %arrayidx = getelementptr i16, ptr %src, i64 %idxprom
  %0 = load i16, ptr %arrayidx, align 2
  %cmp2 = icmp eq i16 %0, 0
  br i1 %cmp2, label %if.then3, label %if.else15

if.then3:                                         ; preds = %while.body
  %1 = load i8, ptr %src, align 1
  %inc = add nsw i32 %srcIndex.03, 1
  %cmp11 = icmp eq i8 %1, 0
  br i1 %cmp11, label %while.cond.backedge, label %if.end13

while.cond.backedge:                              ; preds = %if.else15, %if.then3
  %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ]
  %cmp1 = icmp slt i32 %srcIndex.0.be, %srcLength
  br i1 %cmp1, label %while.body, label %common.ret

if.end13:                                         ; preds = %if.then3
  %call50 = tail call i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32 %destIndex.0.ph)
  %cmp58 = icmp slt i32 %call50, 0
  br i1 %cmp58, label %common.ret, label %while.cond.outer

if.else15:                                        ; preds = %while.body
  %inc33 = add nsw i32 %srcIndex.03, 1
  br label %while.cond.backedge

common.ret:                                       ; preds = %if.end13, %while.cond.outer, %while.cond.backedge
  ret i32 0
}

After:

; ModuleID = 'reduced.ll'
source_filename = "reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

declare i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32) local_unnamed_addr

define noundef i32 @_ZN6icu_7512_GLOBAL__N_17toUpperEijPDsiPKDsP12UCaseContextiPNS_5EditsER10UErrorCode(ptr nocapture readonly %src, i32 %srcLength) local_unnamed_addr {
entry:
  br label %while.cond.outer

while.cond.outer:                                 ; preds = %if.end13, %entry
  %srcIndex.0.ph = phi i32 [ %4, %if.end13 ], [ 0, %entry ]
  %destIndex.0.ph = phi i32 [ 1, %if.end13 ], [ 0, %entry ]
  %cmp12 = icmp slt i32 %srcIndex.0.ph, %srcLength
  br i1 %cmp12, label %while.body.preheader, label %common.ret

while.body.preheader:                             ; preds = %while.cond.outer
  %0 = sext i32 %srcIndex.0.ph to i64
  br label %while.body

while.body:                                       ; preds = %while.body.preheader, %while.cond.backedge
  %indvars.iv = phi i64 [ %0, %while.body.preheader ], [ %2, %while.cond.backedge ]
  %srcIndex.03 = phi i32 [ %srcIndex.0.ph, %while.body.preheader ], [ %srcIndex.0.be, %while.cond.backedge ]
  %arrayidx = getelementptr i16, ptr %src, i64 %indvars.iv
  %1 = load i16, ptr %arrayidx, align 2
  %cmp2 = icmp eq i16 %1, 0
  %2 = add nsw i64 %indvars.iv, 1
  br i1 %cmp2, label %if.then3, label %if.else15

if.then3:                                         ; preds = %while.body
  %3 = load i8, ptr %src, align 1
  %cmp11 = icmp eq i8 %3, 0
  %4 = trunc nsw i64 %2 to i32
  br i1 %cmp11, label %while.cond.backedge, label %if.end13

while.cond.backedge:                              ; preds = %if.else15, %if.then3
  %srcIndex.0.be = phi i32 [ %inc33, %if.else15 ], [ %4, %if.then3 ]
  %cmp1 = icmp slt i32 %srcIndex.0.be, %srcLength
  br i1 %cmp1, label %while.body, label %common.ret

if.end13:                                         ; preds = %if.then3
  %call50 = tail call i32 @_ZN6icu_7512_GLOBAL__N_115appendUnchangedEPDsiiPKDsijPNS_5EditsE(i32 %destIndex.0.ph)
  %cmp58 = icmp slt i32 %call50, 0
  br i1 %cmp58, label %common.ret, label %while.cond.outer

if.else15:                                        ; preds = %while.body
  %inc33 = add nsw i32 %srcIndex.03, 1
  br label %while.cond.backedge

common.ret:                                       ; preds = %if.end13, %while.cond.outer, %while.cond.backedge
  ret i32 0
}

@akshayrdeodhar
Copy link
Contributor Author

Sorry, missed your comment (dtcxzyw/llvm-opt-benchmark#1696 (comment)) on the other MR. Am looking into the reduced case.

@akshayrdeodhar
Copy link
Contributor Author

akshayrdeodhar commented Dec 3, 2024

Looked into this- this is expected behaviour, I think we should ignore this regression. %indvars.iv is created by IndVarSimplify, by widening %srcIndex.03.

Here's the debug output of that pass, for the changed version of the compiler:

Wide IV:   %indvars.iv = phi i64 [ %indvars.iv.next, %while.cond.backedge ], [ %0, %while.body.preheader ]
INDVARS: eliminating   %idxprom = sext i32 %srcIndex.03 to i64 replaced by   %indvars.iv = phi i64 [ %indvars.iv.next, %while.cond.backedge ], [ %0, %while.body.preheader ]
Cloning arithmetic IVUser:   %inc = add nsw i32 %srcIndex.03, 1
INDVARS: Truncate IV   %3 = add nsw i64 %indvars.iv, 1 for user   %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ]
INDVARS: Widen lcssa phi   %inc.lcssa = phi i32 [ %inc, %if.then3 ] to   %inc.lcssa.wide = phi i64 [ %3, %if.then3 ]
Cloning arithmetic IVUser:   %inc33 = add nsw i32 %srcIndex.03, 1

Before the change, the compiler fails to do IV widening.

This is because the new compiler is able to create an AddRecExpr for %srcIndex.03, as it is able to simplify %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ], while the old compiler cannot.

@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 3, 2024

Looked into this- this is expected behaviour, I think we should ignore this regression. %indvars.iv is created by IndVarSimplify, by widening %srcIndex.03.

Here's the debug output of that pass, for the changed version of the compiler:

Wide IV:   %indvars.iv = phi i64 [ %indvars.iv.next, %while.cond.backedge ], [ %0, %while.body.preheader ]
INDVARS: eliminating   %idxprom = sext i32 %srcIndex.03 to i64 replaced by   %indvars.iv = phi i64 [ %indvars.iv.next, %while.cond.backedge ], [ %0, %while.body.preheader ]
Cloning arithmetic IVUser:   %inc = add nsw i32 %srcIndex.03, 1
INDVARS: Truncate IV   %3 = add nsw i64 %indvars.iv, 1 for user   %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ]
INDVARS: Widen lcssa phi   %inc.lcssa = phi i32 [ %inc, %if.then3 ] to   %inc.lcssa.wide = phi i64 [ %3, %if.then3 ]
Cloning arithmetic IVUser:   %inc33 = add nsw i32 %srcIndex.03, 1

Before the change, the compiler fails to do IV widening.

This is because the new compiler is able to create an AddRecExpr for %srcIndex.03, as it is able to simplify %srcIndex.0.be = phi i32 [ %inc, %if.then3 ], [ %inc33, %if.else15 ], while the old compiler cannot.

Can we widen %srcLength and %srcIndex.0.be as well to fully eliminate all uses of %srcIndex.03?

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

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

LG

@akshayrdeodhar
Copy link
Contributor Author

Can we widen %srcLength and %srcIndex.0.be as well to fully eliminate all uses of %srcIndex.03?

This will be an improvement to IndVarSimplify- I'm not familiar with that pass - will it be fine if I land this MR independently of the improvement?

@dtcxzyw
Copy link
Member

dtcxzyw commented Dec 4, 2024

will it be fine if I land this MR independently of the improvement?

Yeah. I don't mean to block this MR.

Copy link
Contributor

@Prince781 Prince781 left a comment

Choose a reason for hiding this comment

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

LGTM

@akshayrdeodhar
Copy link
Contributor Author

Thanks for the reviews!

@akshayrdeodhar akshayrdeodhar merged commit 82c93b6 into llvm:main Dec 6, 2024
8 checks passed
broxigarchen pushed a commit to broxigarchen/llvm-project that referenced this pull request Dec 10, 2024
…identical (llvm#115945)

Helps SCEV analyze some special phi nodes, allowing the computation of
loop trip count in cases like the following:

https://godbolt.org/z/xGs1d81TW
chrsmcgrr pushed a commit to RooflineAI/llvm-project that referenced this pull request Dec 12, 2024
…identical (llvm#115945)

Helps SCEV analyze some special phi nodes, allowing the computation of
loop trip count in cases like the following:

https://godbolt.org/z/xGs1d81TW
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants