<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 --- - Infer nsw/nuw flags for increment/decrement if relational comparison succeeded"
   href="https://llvm.org/bugs/show_bug.cgi?id=30428">30428</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Infer nsw/nuw flags for increment/decrement if relational comparison succeeded
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Keywords</th>
          <td>code-quality
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>matti.niemenmaa+llvmbugs@iki.fi
          </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=17300" name="attach_17300" title="LLVM emitted for simple Rust example">attachment 17300</a> <a href="attachment.cgi?id=17300&action=edit" title="LLVM emitted for simple Rust example">[details]</a></span>
LLVM emitted for simple Rust example

Consider the following example:


define i1 @func(i64 %a, i64 %b, i64 %c) {
  %sgt = icmp sgt i64 %a, %b
  br i1 %sgt, label %greater, label %lesser

greater:
  %add = add i64 %b, 1
  %sgt.add = icmp sgt i64 %add, %c
  ret i1 %sgt.add

lesser:
  ret i1 true
}


At the point where %add is executed we know that %sgt was true, i.e. %a > %b.
We then know that incrementing %b cannot wrap: there is "room" in the value
range for at least %a before we would wrap. More generally:

1. If (X s< Y), then both X + 1 and Y - 1 are nsw.
2. If (X u< Y), then both X + 1 and Y - 1 are nuw. [1]

Currently (LLVM trunk r281814, or release version 3.9.0) this kind of analysis
is not performed. I'm not sure where it would belong, either. It doesn't feel
important enough to me to have its own pass.

This arose from looking at why a bounds check in Rust is not eliminated [2]: it
would require this kind of analysis in addition to my patch from
<a href="https://reviews.llvm.org/D24700">https://reviews.llvm.org/D24700</a> to simplify unsigned comparisons. Attached is a
complete example of LLVM emitted by the Rust compiler including a bounds check
that could be eliminated. Adding a nuw flag to the increment and using a
version of opt that includes D24700, the whole function can be optimized down
to a 'ret void'.

[1]: Due to the current canonicalization from 'sub nuw Y, 1' to 'add Y, -1' the
latter flag would not be so helpful. But as I mention in D24700, this
canonicalization seems misguided to me: keeping the nuw would be useful.
[2]: <a href="https://github.com/rust-lang/rust/issues/35981">https://github.com/rust-lang/rust/issues/35981</a></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>