<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Scalarizer is crashing due to use-after-free"
   href="https://llvm.org/bugs/show_bug.cgi?id=28911">28911</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Scalarizer is crashing due to use-after-free
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Scalar Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>david.stenberg@ericsson.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=16917" name="attach_16917" title="Reproducer">attachment 16917</a> <a href="attachment.cgi?id=16917&action=edit" title="Reproducer">[details]</a></span>
Reproducer

When running the following command:

opt -lint -S -mtriple=x86-64 -scalarizer -verify bugpoint-reduced-simplified.ll

opt crashes due to the following error:

  Instruction does not dominate all uses!
    <badref> = extractelement
    %h.10.2.i0 = phi i16 [ <badref>, %bb3 ]
  LLVM ERROR: Broken function found, compilation aborted!

Running opt with valgrind shows a bunch of invalid reads for an ExtractElement
instruction that has been already deleted:

  [...]
  ==42662== Invalid read of size 8
  ==42662==    at 0x103E118: llvm::Value::getType() const (Value.h:227)
  ==42662==    by 0x13ED204: llvm::PHINode::setIncomingValue(unsigned int,
llvm::Value*) (Instructions.h:2563)
  ==42662==    by 0x13ED317: llvm::PHINode::addIncoming(llvm::Value*,
llvm::BasicBlock*) (Instructions.h:2607)
  ==42662==    by 0x1E8E947: (anonymous
namespace)::Scalarizer::visitPHINode(llvm::PHINode&) (Scalarizer.cpp:663)
  ==42662==    by 0x1E916D0: llvm::InstVisitor<(anonymous
namespace)::Scalarizer, bool>::visitPHI(llvm::PHINode&) (Instruction.def:185)
  ==42662==    by 0x1E90AC8: llvm::InstVisitor<(anonymous
namespace)::Scalarizer, bool>::visit(llvm::Instruction&) (Instruction.def:185)
  ==42662==    by 0x1E8F664: llvm::InstVisitor<(anonymous
namespace)::Scalarizer, bool>::visit(llvm::Instruction*) (InstVisitor.h:114)
  ==42662==    by 0x1E8B035: (anonymous
namespace)::Scalarizer::runOnFunction(llvm::Function&) (Scalarizer.cpp:265)
  ==42662==    by 0x19E145F:
llvm::FPPassManager::runOnFunction(llvm::Function&)
(LegacyPassManager.cpp:1526)
  ==42662==    by 0x19E15F2: llvm::FPPassManager::runOnModule(llvm::Module&)
(LegacyPassManager.cpp:1547)
  ==42662==    by 0x19E198D: (anonymous
namespace)::MPPassManager::runOnModule(llvm::Module&)
(LegacyPassManager.cpp:1603)
  ==42662==    by 0x19E20DD: llvm::legacy::PassManagerImpl::run(llvm::Module&)
(LegacyPassManager.cpp:1706)
  ==42662==  Address 0x62e45d8 is 56 bytes inside a block of size 112 free'd
  ==42662==    at 0x4C2C2BC: operator delete(void*) (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==42662==    by 0x1A4273B: llvm::User::operator delete(void*) (User.cpp:193)
  ==42662==    by 0x19BF14F: llvm::ExtractElementInst::~ExtractElementInst()
(Instructions.h:2005)
  ==42662==    by 0x168F934:
llvm::ilist_node_traits<llvm::Instruction>::deleteNode(llvm::Instruction*) (in
/local/repo/edasten/llvm-upstream/build-latest2/bin/opt)
  ==42662==    by 0x168F3F6: llvm::iplist<llvm::Instruction,
llvm::SymbolTableListTraits<llvm::Instruction>
<span class="quote">>::erase(llvm::ilist_iterator<llvm::Instruction>) (ilist.h:470)</span >
  ==42662==    by 0x19A68CA: llvm::Instruction::eraseFromParent()
(Instruction.cpp:76)
  ==42662==    by 0x1E8B666: (anonymous
namespace)::Scalarizer::gather(llvm::Instruction*,
llvm::SmallVector<llvm::Value*, 8u> const&) (Scalarizer.cpp:320)
  ==42662==    by 0x1E8E9A8: (anonymous
namespace)::Scalarizer::visitPHINode(llvm::PHINode&) (Scalarizer.cpp:665)
  [...]

An initial analysis:

As the shufflevector instruction is visited before the %h.10.1 phi node, an
extractvalue instruction will be created for the %h.10.1 node. This instruction
will be stored in Scattered and Gathered for the shufflevector instruction.

When later visiting the %h.10.1 phi node, the extractvalue instruction will be
deleted and replaced by a scalarized phi node, but it will not be removed from
Scattered and Gathered, leading to stale pointers.

This could be fixed by adding the following code to gather() to make sure that
Scattered and Gathered contains the new instruction:

@@ -317,6 +317,17 @@ void Scalarizer::gather(Instruction *Op, const ValueVector
&CV) {
       Instruction *Old = cast<Instruction>(V);
       CV[I]->takeName(Old);
       Old->replaceAllUsesWith(CV[I]);
+
+      for (auto &P : Scattered) {
+        ValueVector &VV = P.second;
+        std::replace(VV.begin(), VV.end(), V, CV[I]);
+      }
+
+      for (auto &P : Gathered) {
+        ValueVector &VV = *P.second;
+        std::replace(VV.begin(), VV.end(), V, CV[I]);
+      }
+
       Old->eraseFromParent();
     }
   }

I do not have enough knowledge of the Scalarizer to tell if this is the best
way to fix this.
The output does at least look reasonable.

Performance wise this fix is not ideal, but as we have no use information since
the
operands for the previously visited instructions are removed, this was easiest.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>