Skip to content

Conversation

@dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Jun 5, 2025

Similar to 7e14161, the exiting value may be a non-local instruction or an argument.

Closes #142895.

@dtcxzyw dtcxzyw requested a review from fhahn June 5, 2025 15:30
@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Yingwei Zheng (dtcxzyw)

Changes

Similar to 7e14161, the exiting value may be a non-local instruction or an argument.

Closes #142895.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/LoopPeel.cpp (+5-1)
  • (modified) llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll (+41)
diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp
index bd025fddd0cf7..9149f71941db4 100644
--- a/llvm/lib/Transforms/Utils/LoopPeel.cpp
+++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp
@@ -1257,7 +1257,11 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
     // Now adjust users of the original exit values by replacing them with the
     // exit value from the peeled iteration and remove them.
     for (const auto &[P, E] : ExitValues) {
-      P->replaceAllUsesWith(isa<Constant>(E) ? E : &*VMap.lookup(E));
+      Instruction *ExitInst = dyn_cast<Instruction>(E);
+      if (ExitInst && L->contains(ExitInst))
+        P->replaceAllUsesWith(&*VMap[ExitInst]);
+      else
+        P->replaceAllUsesWith(E);
       P->eraseFromParent();
     }
     formLCSSA(*L, DT, LI, SE);
diff --git a/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll b/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
index 7d38c18d10667..f07afaf1b207f 100644
--- a/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
+++ b/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
@@ -71,6 +71,47 @@ exit:
   ret i32 %1
 }
 
+; Test case for https://github.com/llvm/llvm-project/issues/142895.
+
+define i32 @pr142895_exit_value_is_arg(i32 %arg) {
+entry:
+  br label %for.cond.preheader
+
+for.cond.preheader:
+  %indvar = phi i32 [ 0, %entry ], [ %inc, %for.cond.preheader ]
+  %cmp1 = icmp eq i32 %indvar, 32
+  %sel = select i1 %cmp1, i32 0, i32 0
+  %sub = sub i32 0, 0
+  %xor = xor i32 0, 0
+  %inc = add i32 %indvar, 1
+  %exitcond = icmp ne i32 %inc, 33
+  br i1 %exitcond, label %for.cond.preheader, label %for.cond.cleanup
+
+for.cond.cleanup:
+  %exit.lcssa = phi i32 [ %arg, %for.cond.preheader ]
+  ret i32 %exit.lcssa
+}
+
+define i32 @pr142895_exit_value_is_inst(i32 %arg) {
+entry:
+  %mul = mul i32 %arg, 7
+  br label %for.cond.preheader
+
+for.cond.preheader:
+  %indvar = phi i32 [ 0, %entry ], [ %inc, %for.cond.preheader ]
+  %cmp1 = icmp eq i32 %indvar, 32
+  %sel = select i1 %cmp1, i32 0, i32 0
+  %sub = sub i32 0, 0
+  %xor = xor i32 0, 0
+  %inc = add i32 %indvar, 1
+  %exitcond = icmp ne i32 %inc, 33
+  br i1 %exitcond, label %for.cond.preheader, label %for.cond.cleanup
+
+for.cond.cleanup:
+  %exit.lcssa = phi i32 [ %mul, %for.cond.preheader ]
+  ret i32 %exit.lcssa
+}
+
 declare void @foo(i32)
 ;.
 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks

@dtcxzyw dtcxzyw merged commit 4eac8da into llvm:main Jun 6, 2025
11 checks passed
@dtcxzyw dtcxzyw deleted the fix-142895 branch June 6, 2025 04:56
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.

[LoopPeel] Assertion `V && "Dereferencing deleted ValueHandle"' failed.

3 participants