[llvm] abd2dc9 - [VectorCombine] Avoid double deletion in `eraseInstruction` (#155621)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 27 07:28:06 PDT 2025


Author: Yingwei Zheng
Date: 2025-08-27T22:28:02+08:00
New Revision: abd2dc90c039cf8b3907f096743fc69380c8b245

URL: https://github.com/llvm/llvm-project/commit/abd2dc90c039cf8b3907f096743fc69380c8b245
DIFF: https://github.com/llvm/llvm-project/commit/abd2dc90c039cf8b3907f096743fc69380c8b245.diff

LOG: [VectorCombine] Avoid double deletion in `eraseInstruction` (#155621)

Consider the following pattern:
```
C = op A B
D = op C
E = op D, C
```
As `E` is dead, we call `eraseInstruction(E)` and see if its operands
become dead. `RecursivelyDeleteTriviallyDeadInstructions(D)` also erases
`C`, which causes a UAF crash in the subsequent call
`RecursivelyDeleteTriviallyDeadInstructions(C)`.

This patch also adds deleted ops into the visit list to avoid double
deletion.

Closes https://github.com/llvm/llvm-project/issues/155543.

Added: 
    llvm/test/Transforms/VectorCombine/X86/pr155543.ll

Modified: 
    llvm/lib/Transforms/Vectorize/VectorCombine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 56a08b8438718..c88ed95de2946 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -173,15 +173,16 @@ class VectorCombine {
     // further folds that were hindered by OneUse limits.
     SmallPtrSet<Value *, 4> Visited;
     for (Value *Op : Ops) {
-      if (Visited.insert(Op).second) {
+      if (!Visited.contains(Op)) {
         if (auto *OpI = dyn_cast<Instruction>(Op)) {
           if (RecursivelyDeleteTriviallyDeadInstructions(
-                  OpI, nullptr, nullptr, [this](Value *V) {
+                  OpI, nullptr, nullptr, [&](Value *V) {
                     if (auto *I = dyn_cast<Instruction>(V)) {
                       LLVM_DEBUG(dbgs() << "VC: Erased: " << *I << '\n');
                       Worklist.remove(I);
                       if (I == NextInst)
                         NextInst = NextInst->getNextNode();
+                      Visited.insert(I);
                     }
                   }))
             continue;

diff  --git a/llvm/test/Transforms/VectorCombine/X86/pr155543.ll b/llvm/test/Transforms/VectorCombine/X86/pr155543.ll
new file mode 100644
index 0000000000000..b161c0aaf031c
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/X86/pr155543.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- | FileCheck %s
+
+; Make sure we don't double delete a dead instruction.
+
+define void @pr155543() {
+; CHECK-LABEL: define void @pr155543() {
+; CHECK-NEXT:    ret void
+;
+  %shuffle1 = shufflevector <4 x double> poison, <4 x double> poison, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 0, i32 1, i32 2, i32 3>
+  %shuffle2 = shufflevector <8 x double> poison, <8 x double> %shuffle1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
+  %fadd = fadd <8 x double> %shuffle1, zeroinitializer
+  %dead = shufflevector <8 x double> %fadd, <8 x double> %shuffle2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
+  ret void
+}


        


More information about the llvm-commits mailing list