<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 - SimplifyCFG loses information while processing switch"
   href="https://bugs.llvm.org/show_bug.cgi?id=50455">50455</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SimplifyCFG loses information while processing switch
          </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>degiotheo@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hello.

I am working on an optimization in rustc that is lost by LLVM. When processing
switch statements for which the "otherwise" branch is an unreachable block, the
SimplifyCFG pass loses information on the fact that the input is within a
finite set, preventing further optimizations. Here is an example:

```
define i64 @demo(i64 %x) {
entry:
    switch i64 %x, label %bb3 [
        i64 0, label %bb1
        i64 1, label %bb2
    ]
bb1:
    ret i64 0
bb2:
    %0 = icmp eq i64 %x, 100 ; this will necessarily be false because %x == 1
    br i1 %0, label %bb4, label %bb5
bb3:
    unreachable
bb4:
    ret i64 200
bb5:
    ret i64 10
}
```

when optimized using

```
opt --simplifycfg -S -o repro.out.ll repro.ll
```

is turned into

```
; ModuleID = 'repro.ll'
source_filename = "repro.ll"

define i64 @demo(i64 %x) {
entry:
  %switch = icmp ult i64 %x, 1
  %0 = icmp eq i64 %x, 100
  %. = select i1 %0, i64 200, i64 10
  %merge = select i1 %switch, i64 0, i64 %.
  ret i64 %merge
}
```

which loses the fact that x is either 0 or 1, and thus the useless `icmp` and
`select` will not be eliminated.

Alternatively, is there a good way to ensure the pass does not miss out on
this?

If nobody is available to help us with this, I am eager to work on this myself.
However, I would need a bit of mentoring as I have never contributed to LLVM
before.

Thanks in advance!</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>