<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 - ScalarEvolution Add expression type tracking woes"
   href="https://bugs.llvm.org/show_bug.cgi?id=46457">46457</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>ScalarEvolution Add expression type tracking woes
          </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>Global Analyses
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>lebedev.ri@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>SCEVAddExpr contains the following:

    Type *getType() const {
      // Use the type of the last operand, which is likely to be a pointer
      // type, if there is one. This doesn't usually matter, but it can help
      // reduce casts when the expressions are expanded.
      return getOperand(getNumOperands() - 1)->getType();
    }

That's great, we've saved whole sizeof(pointer) bytes, and it *almost* always
works.
Except it's very much not guaranteed, and can break.

For example, see: <a href="https://godbolt.org/z/L8BZyJ">https://godbolt.org/z/L8BZyJ</a>
  %arrayidx1 = getelementptr inbounds [1 x i8], [1 x i8]* %arrayidx, i64 0, i64
%sub.ptr.div
  -->  ({((sext i32 %base to i64) + %e)<nsw>,+,1}<nsw><%for.cond> +
%sub.ptr.div)<nsw> U: full-set S: full-set      Exits: <<Unknown>>         
LoopDispositions: { %for.cond: Variant }

Last operand is `%sub.ptr.div`, which is not a pointer, but first operand *is*
pointer.
So the SCEV has non-pointer type, even though it really should be
pointer-typed.

Granted, this does not directly matter for expander, it takes extra care
to re-order ops (via LoopCompare) so that pointer operand[s] are first.
But what will happen if we happen to go one layer up, if we happen to be
expanding
an expression that has such a mistyped operand? I can't imagine it would handle
it well.

But my main (original) problem with this is that
`ScalarEvolution::getPointerBase()` simply gives up in such cases.

Now, i'm not sure how best to fix this.
I see 3 main paths:
* Teach complexity sorting to partition pointer-typed operands and non-pointer
typed operands.
  I don't believe this is the way, it breaks the entirety of complexity/scev
type grouping.
* Before actually creating SCEVAddExpr, partition operands so that the
non-pointer-ones are first.
  Would this work in general thought? 
* Just store the type in SCEVAddExpr, don't hope that we guess it right.

So, unless i'm missing something obvious, how about we do the latter, and just
store the type?</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>