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

    <tr>
        <th>Summary</th>
        <td>
            [SimplifyCFG] Chain of ICMPs not optimised to switch 
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:optimizations,
            missed-optimization
      </td>
    </tr>

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

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

<pre>
    `
bool cond_as_ret(int c) {
    bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
    return r;
}


int cond_in_select(int c) {
    bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
    return r ? 1 : -1;
}

int cond_in_br(int c) {
    bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
    if(r) return 1;
    else return -1;
}`

`
define dso_local zeroext i1 @cond_as_ret(i32 noundef %0) local_unnamed_addr #0 {
  %2 = icmp eq i32 %0, 101
  %3 = and i32 %0, -5
  %4 = icmp eq i32 %3, 104
  %5 = or i1 %2, %4
  %6 = icmp eq i32 %0, 111
  %7 = or i1 %6, %5
  %8 = icmp eq i32 %0, 119
  %9 = or i1 %8, %7
  %10 = icmp eq i32 %0, 0
  %11 = or i1 %10, %9
  ret i1 %11
}

define dso_local i32 @cond_in_select(i32 noundef %0) local_unnamed_addr #0 {
  %2 = icmp eq i32 %0, 101
  %3 = and i32 %0, -5
  %4 = icmp eq i32 %3, 104
  %5 = or i1 %2, %4
  %6 = icmp eq i32 %0, 111
  %7 = or i1 %6, %5
  %8 = icmp eq i32 %0, 119
  %9 = or i1 %8, %7
  %10 = icmp eq i32 %0, 0
  %11 = or i1 %10, %9
  %12 = select i1 %11, i32 1, i32 -1
  ret i32 %12
}

define dso_local i32 @cond_in_br(i32 noundef %0) local_unnamed_addr #0 {
  switch i32 %0, label %2 [
    i32 119, label %3
    i32 111, label %3
    i32 108, label %3
    i32 104, label %3
    i32 101, label %3
    i32 0, label %3
  ]

2:                                                ; preds = %1
  br label %3

3:                                                ; preds = %1, %1, %1, %1, %1, %1, %2
  %4 = phi i32 [ -1, %2 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ]
  ret i32 %4
}`



cond_in_br case is handled by SimplifyCFGOpt::SimplifyBranchOnICmpChain. Generalization would help to handle more forms.

GCC emits very nice code for all three functions, something what we want as well.

Godbolt: https://godbolt.org/z/YYYhK4fcG

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztVl1v8yYU_jXOzVEijOMkvshFmyrVq2l6J-2qVxUxJGbD4AFulv76HWwnxW0aba-mSZVm2RjOeXg4XwbvDD-tkwVJyENC7nbGKCiN5s_MPVvhE7qS2kOZ0AKS5X0PArw6oIUkewDElKHT95cVPojdQCwU14TqmtBcEx6vCZN8Q8KLFkkWWYZWt1aDvQiT5cPQidrOq-Cn1M9OKFF-ZVcRuYUU2zuYpp_5HXu8s1_QW7lHg2wwePA7HamFcuKseReFc3UP7XnIxV5qAdyZZ2VKpuBVWCP-9CAxlnPy7jPIKGjTapyENuYk2NHNem61ZrVAKOcYN5qROKAIpV0wZVk3IP6AwNPP30BK0giXdTim-QgzzSPI_BpV1lPNI1ze4YztPEELAiJMjyCLz61KY6uWY6rFQBVbtbpBVUS4Yky1GqiWESQln3KRGJaOqVIycF2Ww6SddenVz-FD8ru1hqyPNoX_E_-VEh-EfeD7DL5VAQID7aUzTUfF0q-Y0h-qln5D_bFKcUfpy2rksmI7oYYSyuMtMNiPoY0h2Xt1elNNVrfV89vqm-TkujLJR7Gk4Zz6hxdu59BYwd1wMOWX3O3shxX7Nvt3lunL6---6Ydvtqlkn9r8PlTcAOtiEvoovXD8t8KPtT__9MSM2reKh5LhiSsdVLh1KcFhd4JfZd0ouT9tto_fG48ZwPssu7dMl9V3_W1TN5uKST2DR6GFZUq-Mi-NhqNpFYdKqAa8GWihNlbA3tjazWI7HjcbELX0Dl6EPYGWpcDfG95BgSkFvrICR60uA7cLvjtTC19JfYBjxTwcBRwZ_gQxh12lxvSG74wKHkDlfeOCK3SL96FXzIw94OgVn6enp-qn-b587GdO-DrjRVawiZdeiTVGPooKRh4658Hs4dvm518cbhkeTONlLR0GER0fNoRJa9X63eLSV-1uVpoaB0q9nF_TxprfuuNqK51rBXq7zRdktZxU61W24JlIKaMLtpiXNF0VvOCC8AKHS5JPus_HBTsTSjvS7K63p08Lkg3nCEUT0cZprA3K_GEi15RQShbpMs1SQrNZsV_Oi4wwylKx2mcZbpaiZlLNwgohehO77kzftQeHSiWdd29K5pw8aNGFL_Cz1lfGrjl7kSH-L0y730-Tztl15-lfPt83Ug">