<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 - Missed optimization: CorrelatedValuePropagationPass doesn't run by default after inlining"
   href="https://bugs.llvm.org/show_bug.cgi?id=46626">46626</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Missed optimization: CorrelatedValuePropagationPass doesn't run by default after inlining
          </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>All
          </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>Interprocedural Optimizations
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>vlad@tsyrklevich.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The following reproducer:
$ cat ex.c
static int a;
static int *b(int *c) { return c; }
int foo() {
  if (a == 0)
    a = 2;
  return *b(&a);
}

demonstrates a missed optimization due to not running the
CorrelatedValuePropagationPass after inlining. Compiled to IR, it looks like:
$ clang -S -emit-llvm ex.c -o ex.ll -O2
$ cat ex.ll
...
define i32 @foo() local_unnamed_addr #0 {
  %1 = load i1, i1* @a, align 4
  %2 = select i1 %1, i32 2, i32 0
  br i1 %1, label %4, label %3

3:                                                ; preds = %0
  store i1 true, i1* @a, align 4
  br label %4

4:                                                ; preds = %0, %3
  %5 = phi i32 [ 2, %3 ], [ %2, %0 ]
  ret i32 %5
}
...

By running opt on this clang -O2 output, we get simpler IR:
$ cat ex.ll | opt -S -O2
...
define i32 @foo() local_unnamed_addr #0 {
  %1 = load i1, i1* @a, align 4
  br i1 %1, label %3, label %2

2:                                                ; preds = %0
  store i1 true, i1* @a, align 4
  br label %3

3:                                                ; preds = %2, %0
  ret i32 2
}
...

The difference between the IR for these 2 functions results in the first being
12 bytes larger when compiled on AArch64. The following trivial change 'fixes'
the reproducer given above, but I'm not clear on where in the pipeline the
CorrelatedValuePropagationPass actually belongs. This diff merely shows the
earliest point that pass can be added which fixes the reproducer.
--- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
+++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
@@ -668,6 +668,7 @@ void PassManagerBuilder::populateModulePassManager(
   // faster.
   if (RunInliner) {
     MPM.add(createGlobalOptimizerPass());
+    MPM.add(createCorrelatedValuePropagationPass());
     MPM.add(createGlobalDCEPass());
   }</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>