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

    <tr>
        <th>Summary</th>
        <td>
            EarlyCSE misses redundant load elimination from base pointer, but succeeds when the pointer has a non-zero offset
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          GINN-Imp
      </td>
    </tr>
</table>

<pre>
    For the following case, EarlyCSE fails to eliminate a redundant load `store i8 %5, ptr @g2, align 1 --> store i8 %2, ptr @g2, align 1`. 
As a result, subsequent passes were not optimized further (`store i8 %5, ptr @g2, align 1 --> store i8 0, ptr @g2, align 1`).

In contrast, if the pointer is offset using getelementptr (e.g., gep %ptr, 32), the same redundant load pattern is optimized correctly.

Godbolt: https://godbolt.org/z/5GzT9qT9j
alive2 proof: https://alive2.llvm.org/ce/z/Tb5mbH

the reduced case:
```llvm
@g1 = external global i32
@g2 = external global i8

define void @src(ptr readonly captures(none) %0) local_unnamed_addr #0 {
  %2 = load i8, ptr %0, align 8
  %3 = zext i8 %2 to i32
  store i32 %3, ptr @g1, align 4
  %cond = icmp eq i8 %2, 0
  br i1 %cond, label %4, label %common.ret

common.ret: ; preds = %4, %1
  ret void

4: ; preds = %1
  %5 = load i8, ptr %0, align 8
  store i8 %5, ptr @g2, align 1      ; can be optimized to store i8 %2, ptr @g2, align 1
  br label %common.ret
}
```

opt -O3 didn't do anything to optimize it.

the case that can be optimized:
```llvm
define void @src2(ptr readonly captures(none) %0) local_unnamed_addr #0 {
  %2 = getelementptr inbounds nuw i8, ptr %0, i64 32
  %3 = load i8, ptr %2, align 8
  %4 = zext i8 %3 to i32
  store i32 %4, ptr @g1, align 4
  %cond = icmp eq i8 %3, 0
  br i1 %cond, label %5, label %common.ret

common.ret: ; preds = %5, %1
  ret void

5: ; preds = %1
  %6 = load i8, ptr %2, align 8
  store i8 %6, ptr @g2, align 1
  br label %common.ret
}
```

early-cse on src2:
```
 - %6 = load i8, ptr %2, align 8
 - store i8 %6, ptr @g2, align 1
+ store i8 %3, ptr @g2, align 1
```

The reduced case is derived from https://github.com/c3lang/c3c/blob/125436d23ef9b7f69837a00ffec168c52839a1dc/src/compiler/llvm_codegen_expr.c#L2376.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0ls9u2zgTwJ-GvgwsSKQkSwcdnLbuV-BD97C5BxQ5kllQpEpSSZOnX5C2UztJA2931zBgU5x_nPlRM9x7NRrEjlQ3pPq44kvYW9d9_vL16_rLNK96Kx-7nXUQ9giD1do-KDOC4B4J_QCfuNOPH_78BANX2kOwgFpNyvCAwMGhXIzkJoC2XAKpcx-sQ1ANEFpV0cAcHJAyH2lccK1GAwWs14R9gnNZ-itZUucZkHy79cmfX3SIu37pPX5f0ASYuffo4QEdgrEB7BzUpJ5QwrC4sEcHhDa_G1r-TlyEthnJtyTffjEgrAmO-xScGlI2Z6tMQAfKgx0GjwEWH3M7YkCNE5qQDNMGszGLeiPOMbg5uLhilNA2_om2PJ_wZbpnHgI6k-w_n1lY51AE_XgM7bOVvdWBsC3sQ5g9YVtCd4TuxsNGZt1I6O6J0F31-em2_X7bfiP5lmt1jxRmZ-3wWvewm2l9Px31BR6N3PbV1P_v4DsGHmMWMa4IFItPY-bSN6rHdZmPBRD2EfBHPA_XMGrbcw2K0eM-fXu_OfiROCiDcG-VjHXyThDaxNw65NIa_QiCz2Fx6AltjDVIaBsTHSsI2gqu7xZj-ITyjksZS8JyIJsbkm8hwZm8p5yr5hmIpH_ioTnJsiT7hD_Ciex4aQ4ngRNXjCbRc7aKn7bKky1hjUzmlJhmwO_ndyVPQr0DVZxE42PNe9TxQXmxEnaarMkchkPGztZsC4TdwOxQ-uTspExoVSQnDkPK7UG1fFOjOMVcXZur665j-kRvghvo8Qz0YK98gRzz9ItcbD6eI3k4op0DrP9gIJU0hG4CSAvcPIZ9vL3BPgcBKmQ_SY-EQ9jz8CrWt7l_TS39L7C9fNso09vFSA9meXijQKou4YjqM8uva0nf4L58yT37Jfflb3LPruG--ifcV-9wX73PfX1trs6hrf9FaDF26rXwCNZAgumSumhy_XciXV8dKqE3F7LsPdnLqG9ftIjYzCQ6dR_bt7PTy6alwn7pM2Gn2HOY5iY1HyYI3fXa9oTuClqVrJaU4dD2m6FuG7bheT4MKIq6ERVtWMsLGTVSo9gJO81KoyN0F2_mnbASRzR3-GN2mSCU_Z-yTZ2tZMdky1q-wq7YlHXFaNXkq31Xs7ooh00rkbdc1AOiFHVFc1k2smz7zUp1NKdVXuV1UVR10WZDW6HIm3rgZc9LgaTMceJKPzfUlfJ-wa5gTb1pVgkCnwY4Sg0-QNollMZ5znVRad0voydlrpUP_qeZoILG7nmGm1SalF6MEaeBTllzSHkf63AcXmLx-iWAX4TAyP3DHs3FdLPncTIz1qyf0NnjpLNanO7eKV16BR5-1rOz31AEQnfpXD7W8HDw-47-FQAA__832C8I">