<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Unnecesary use of incorrect cast in InstructionCombining is causing assertion failure"
   href="https://bugs.llvm.org/show_bug.cgi?id=51485">51485</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Unnecesary use of incorrect cast in InstructionCombining is causing assertion failure
          </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>enhancement
          </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>pawel.osmialowski@foss.arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Although this is the same assertion as in #46596, it is not caused by the same
problem.

The affected code in llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
does a cast to GetElementPtrInst in order to have an
ability to call setIsInBounds() method. Unfortunately, the Value*
pointer returned by the CreateGEP() method does not pass the
isa<GetElementPtrInst> test checked by the assertion in the cast method. When
using the compiler built with assertions enabled, it causes the following
assertion failing (while running LTO compilation mode):

ld: llvm/include/llvm/Support/Casting.h:276: typename llvm::cast_retty<X,
Y*>::ret_type llvm::cast(Y*) [with X = llvm::GetElementPtrInst; Y =
llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type =
llvm::GetElementPtrInst*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of
incompatible type!"' failed.
PLEASE submit a bug report to <a href="https://bugs.llvm.org/">https://bugs.llvm.org/</a> and include the crash
backtrace.
Stack dump:
0.      Running pass 'Function Pass Manager' on module 'ld-temp.o'.
1.      Running pass 'Combine redundant instructions'

Note that this issue is not easy to reproduce and might have stayed
like that for a very long time. The only reason it has revealed itself
was due to our recent works on LTO compilation mode during which we
have tried the compiler with the assertions enabled. The problem
manifested itself eventually when we tried to build a bulky benchmark which is
significant in size.

Turns out that the cast which results in the assertion failure can be easily
avoided as such:

--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2198,9 +2198,9 @@ Instruction
*InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
             // -- have to recreate %src & %gep
             // put NewSrc at same location as %src
             Builder.SetInsertPoint(cast<Instruction>(PtrOp));
-            auto *NewSrc = cast<GetElementPtrInst>(
-                Builder.CreateGEP(GEPEltType, SO0, GO1, Src->getName()));
-            NewSrc->setIsInBounds(Src->isInBounds());
+            auto *NewSrc = Src->isInBounds() ?
+              Builder.CreateInBoundsGEP(GEPEltType, SO0, GO1, Src->getName())
:
+              Builder.CreateGEP(GEPEltType, SO0, GO1, Src->getName());
             auto *NewGEP = GetElementPtrInst::Create(GEPEltType, NewSrc,
{SO1});
             NewGEP->setIsInBounds(GEP.isInBounds());
             return NewGEP;</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>