<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/59694>59694</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Missed optimization: constant propagation with a pointer to a const local
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          haberman
      </td>
    </tr>
</table>

<pre>
    Repro:

```c
void ExternFunc(const int*);

int Bad() {
  const int i = 0;
  const int* pi = &i;
 ExternFunc(pi);
  return *pi;
}

int Good() {
  const int i = 0;
  ExternFunc(&i);
  return i;
}
```

Output from trunk (Godbolt link: https://godbolt.org/z/KT8dPM9ac):

```asm
Bad: # @Bad
        push    rax
        mov dword ptr [rsp + 4], 0
        lea     rdi, [rsp + 4]
        call ExternFunc@PLT
        mov     eax, dword ptr [rsp + 4]
        pop rcx
        ret
Good:                                   # @Good
 push    rax
        mov     dword ptr [rsp + 4], 0
        lea rdi, [rsp + 4]
        call    ExternFunc@PLT
        xor     eax, eax
        pop     rcx
        ret
```

In `Good()`, Clang correctly performs constant propagation on the local `i`, even though the pointer escapes, because `i` is a `const` object that cannot be modified by `ExternFunc()` without invoking UB.

In `Bad()`, we have basically the same scenario, except in this case Clang does not perform the constant propagation. `pi` is not merely a const pointer, it is a pointer to a const object, and therefore the value it points to is guaranteed to be stable even across a function call where the pointer escapes. But Clang doesn't seem to realize this, and re-loads `i` after the function call, even though `i` is a const object.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVduO4jgQ_RrzUmoUnATCQx6gexmtdkc7Ws1-QMUuiLcdO7Id-vL1KzuBBoaZnbEQUVyXc-pU2UHv1cEQ1azcsvJphkNoratbbMh1aGaNlW_139Q7y_INy55YdvpfZuNPjO9HqyT89hrImd1gBOOVsMYHUCYwvmF8zfLtZbwyAbYoGa8YXwNbTUaAcxgoYPkTZOfACxvjG-hHO-NL9eFyxaBXl7gAjsLgDDC-6T9C2Orpltcna3-R2BVsYnQP-B7oScZLDn8NoR8C7J3tILjBPAPj1ScrG6sDaGWeWb6BNoTex6bwHeO7w2idW3dgfPfO-O6Pr5X88nmNIlG53zv03bgTO5FvgPEcWJHFt4n5uPrBt_Hp8PXa0NkjyBfrJPTBASu3zvfA-BYKVj4x_gjZtb8mTE8nVbTeBlz5CtT6Utgi-_Ln12_h4yJ8jem-z-S6GtuDEzeVOArjRmp-ft7_wZrUSgFjrh_qFNevavXTOgH8j1Sv1l1KRbcMoyiJ-neFuTuqvxtgy-zjwEQzf4RHjeYAwjpHIug36Mntrev8eIjQBOid7fGAQVkD1kBoCbQVqGM6NWWhI0WLHQ5tcuitMoEckBfYk48uDQkcPJ2iQHnA-JJw4oZt_iURILQYQKAxNkBD0Fmp9ookNG_R--b4xirgRUXkeOCP9lmZA_yznX9b-fkKmyi_ELR4JGjQq9iYt0TcY0fgBRl0yqbKXgX1MTeEVnkQ6GnSTFryEFlOkqX4e6rNI3x_KjpGdORIvwFON9WkVoRTYRTmJGCwZ69Rn-iERkYwR3vrKMEeUQ8Ug1Ocj2HKw2FAhyYQybjREPiAjaaxWyic9RFqPxiRmpvG8yXmvdfDOWyHcFG6YXwVwBN1Mbkj1Oqdkkgnio4etEXpzy3HfSqppWvM2wG6mpDL2uczWedyna9xRvViuVqss7Ksillby8WCaM2rpiEhykqKsiqLSmJeySXmKzlTNc84X3BeLKpFnhXzpRQLrFaLrJB8uZDEiow6VHqu9bGLl_NMeT9QXa6X62KmsSHt06eXc0MvkIyM8_gldnWMeWiGg2dFppUP_iNLUEFT_Vl5TxJsH1Sn3tNUxJvr7hmL43x_AtKxmw1O1zefFBXaoZkL2zG-i8jT46F3dpyZXeLrGd-lev4LAAD__-ryc-8">