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

    <tr>
        <th>Summary</th>
        <td>
            [LICM] Missed optimization: var_9 ? (var_1 ? 1 : 2) : 2222 (Clang16 vs Clang10)
        </td>
    </tr>

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

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

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

<pre>
    Hello, I noticed that in the code below, `var_9 ? (var_1 ? 1 : 2) : 2222` is actually a loop invariant, but clang16 still uses some instructions to calculate it in the loop:

https://godbolt.org/z/bznTsW1oe
```C
extern int var_20;
extern int var_28;
void test(int var_1, int var_2, int var_9) {
    for (int i_18 = 0; i_18 < (var_2 - 1821355268); i_18 += 1) 
 {
        if (var_1)
        {
            var_20 += 1;
 }
        var_28 += var_9 ? (var_1 ? 1 : 2) : 2222;
        

 i_18+=i_18/3;
    }
}
```

Clang16 -O2:
( It's mostly in block `if.end` )
```
entry:
  %sub = add nsw i32 %var_2, -1821355268
  %cmp14 = icmp sgt i32 %var_2, 1821355268
  br i1 %cmp14, label %for.body.lr.ph, label %for.cond.cleanup

for.body.lr.ph: ; preds = %entry
  %var_28.promoted = load i32, ptr @var_28, align 4
  %var_20.promoted = load i32, ptr @var_20, align 4
  %tobool.not = icmp eq i32 %var_1, 0
  %tobool1.not = icmp eq i32 %var_9, 0
  br label %for.body

for.cond.for.cond.cleanup_crit_edge: ; preds = %if.end
  store i32 %add4, ptr @var_28, align 4
 br label %for.cond.cleanup

for.cond.cleanup: ; preds = %for.cond.for.cond.cleanup_crit_edge, %entry
  ret void

for.body:                                         ; preds = %for.body.lr.ph, %if.end
  %i_18.017 = phi i32 [ 0, %for.body.lr.ph ], [ %add6, %if.end ]
  %add1216 = phi i32 [ %var_20.promoted, %for.body.lr.ph ], [ %add11, %if.end ]
  %add41315 = phi i32 [ %var_28.promoted, %for.body.lr.ph ], [ %add4, %if.end ]
  br i1 %tobool.not, label %if.end, label %if.then

if.then:                                          ; preds = %for.body
  %add = add nsw i32 %add1216, 1
  store i32 %add, ptr @var_20, align 4
  br label %if.end

if.end: ; preds = %if.then, %for.body
  %add11 = phi i32 [ %add, %if.then ], [ %add1216, %for.body ]
  %cond = phi i32 [ 1, %if.then ], [ 2, %for.body ]
  %spec.select = select i1 %tobool1.not, i32 2222, i32 %cond
  %add4 = add nsw i32 %add41315, %spec.select
  %div = sdiv i32 %i_18.017, 3
  %add5 = add nsw i32 %i_18.017, 1
  %add6 = add i32 %add5, %div
  %cmp = icmp slt i32 %add6, %sub
  br i1 %cmp, label %for.body, label %for.cond.for.cond.cleanup_crit_edge
```

But clang10 -O2 does a great job: 
```
entry:
  %sub = add nsw i32 %var_2, -1821355268
  %cmp12 = icmp sgt i32 %var_2, 1821355268
  br i1 %cmp12, label %for.body.lr.ph, label %for.cond.cleanup

for.body.lr.ph: ; preds = %entry
  %tobool = icmp ne i32 %var_1, 0
  %tobool1 = icmp eq i32 %var_9, 0
  %cond = select i1 %tobool, i32 1, i32 2
  %spec.select = select i1 %tobool1, i32 2222, i32 %cond
  %var_28.promoted = load i32, i32* @var_28, align 4
  br label %for.body

for.cond.for.cond.cleanup_crit_edge:              ; preds = %if.end
  store i32 %add4, i32* @var_28, align 4
  br label %for.cond.cleanup

for.cond.cleanup:                                 ; preds = %for.cond.for.cond.cleanup_crit_edge, %entry
  ret void

for.body:                                         ; preds = %for.body.lr.ph, %if.end
  %add414 = phi i32 [ %var_28.promoted, %for.body.lr.ph ], [ %add4, %if.end ]
  %i_18.013 = phi i32 [ 0, %for.body.lr.ph ], [ %add6, %if.end ]
  br i1 %tobool, label %if.then, label %if.end

if.then:                                          ; preds = %for.body
  %0 = load i32, i32* @var_20, align 4
  %add = add nsw i32 %0, 1
  store i32 %add, i32* @var_20, align 4
  br label %if.end

if.end:                                           ; preds = %if.then, %for.body
  %add4 = add nsw i32 %add414, %spec.select
  %div = sdiv i32 %i_18.013, 3
  %add5 = add nsw i32 %i_18.013, 1
  %add6 = add i32 %add5, %div
  %cmp = icmp slt i32 %add6, %sub
  br i1 %cmp, label %for.body, label %for.cond.for.cond.cleanup_crit_edge
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcWE1v4zYT_jX0ZRCBpD5sH3xIYhjvAu-ilwJFewkokbG5pUVVpLzN_vqC1LcsJ8pud4vWCGyKnC_OPEM-ETNGHnMhdih-QPF-xSp70uXut1_jKFmlmr_s_ieU0og-wgfItZWZ4GBPzILMwZ4EZJoLSIXSn50MSvCFlU9bQOEBEN24B-If3Pc9UES39YBSihIM0gDLbMWUegEGSusCZH5hpWS5dQbTykKmWH4kCRgrlYLKCANGnwXI3NiyyqzUuQGrIWMqqxSzAmQXnrOIwnuE9wg33ydrC-Pm6AHRw1HzVCsb6PKI6OELoof0S_6z-YVo0SgluP57rJ_Fn1aUOcjcgtsdxSh8mF_ZdCsXLTlYYSyim3aZuO11ssOHrU_SutEFAHjWJTSq8olsAIV7cH7bp8c21xTugGwoCeOYJhtEt70QfXBaxNuuDY9cuI987mrmVEdrV8LuUyegt93uF9B6P5auE9JKvgMj4cTtsJJ-Z7XJenQIR_JdFP2gLebQzGODr7ufaA8VuoEPFtG1gbM2Vr04QKVKZ787jMvnQOTc4bfL08SyyG350lkDQDQ2VeoLxziH3HwGGVI33ZX_blC4Xis7FyTyejI7F2CO9krxWi8tQZJO28kolgrlZp51Gbi-DlQZFKerpUznPMiUYHlVDHM0UQvvwSGrKAU3PjhE43rLfeR1yYOi1GdtBfdiSjPu4nd-C1sCinDTKvQRmJLHHKKpCbzMBJ43YXWqtQpybfskij-GOfSNiK9UyGs625FOWl7nd5o8n9hphp-yUtonwY9iNqMNzBovxupStEEwzqMFSZxG9lp5R2tz4SzZhrsDJlAohQV3AM7ByflZ-pmNZwzlq5y5iSeyCTBZe63iJOsMxg-AG42xGUDx3i_ED02ek5Flv95bZ5wTSpIr49fgXeiNkDfcRSQk8U1_m_f6i2666w6RvoVGx0WT6cmUPYl8WOl26h2Fvl3pcSbmTtOmHv5YvNU4S06OYeMMIdVtys3c6Fm_33H2J4ghc_VrIuttzICj2drA8gQgri2vjJPbdunr5kwhssAIJbL6KGyGQ1yQFhjOm7-ym3ETzQS9N4rmUd3EMnA6UObyUofgBo1i29tOMRw7iuccDeXJWD7p5Pug2oC4vIxv5MF9rOxAoS2OqdK5q3j2Ip6_gl85Ym8TmYeOLGNHZoBrYYDBsRTMwiedesB-d7ZCv4mt0H-IrdRg7kPPxRKOsIwfDPtypoPahiFdF72zA5d131t8zP_cv0rJ_iai8_phv4D1fEWo72E-X3U__fuYkT92ox9BJfqjN_wONGxCVGYZyQxx-QEkBb_VZDf-ablBbvCbtGaB-aXM5hsysYQD3SYC0dfSgPCdNCD8z9GAFd-FfBtu2UrsSLIlOKY0oavTLsE8IiIRzyHbMPEcblmCY7aNkzWJ0jRer-SOYhriDQ7xJoooCSKKk2zL4iQLGdtSjiIszkyqQKnLOdDlcSWNqcQuicJ1tPKRG_8SkdJcfAa_iChF8X5V7pzOXVodDYqwksaa3oqVVvm3j___8PgRxXv4KI0RHHRh5Vl-YVZq35fLXxk5gfaVzsVAPcSIbldVqXaTt3_Snqo0yPQZ0YOLqfm5K0r9yQGPHvxODKIHv9O_AgAA__9yJL8A">