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

    <tr>
        <th>Summary</th>
        <td>
            `switch` not recognized as equivalent to `sext`
        </td>
    </tr>

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

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

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

<pre>
    Opt transformation showing suboptimal current result on trunk: <https://llvm.godbolt.org/z/jj6vcv5q3>
Alive2 demonstration that the proposed transformation is correct: <https://alive2.llvm.org/ce/z/hAAoh_>
Original motivating example in https://github.com/rust-lang/rust/issues/95313: <https://rust.godbolt.org/z/dvYe9r78c> 

The following code:
```llvm
define i32 @src(i8 noundef %0) {
start:
  %1 = alloca i32, align 4
  %order = alloca i8, align 1
  store i8 %0, i8* %order, align 1
  %_2 = load i8, i8* %order, align 1, !range !2, !noundef !3
  switch i8 %_2, label %bb2 [
    i8 -1, label %bb3
    i8 0, label %bb4
    i8 1, label %bb1
  ]

bb2:                                              ; preds = %start
  unreachable

bb3:                                              ; preds = %start
  store i32 -1, i32* %1, align 4
  br label %bb5

bb4:                                              ; preds = %start
  store i32 0, i32* %1, align 4
  br label %bb5

bb1:                                              ; preds = %start
  store i32 1, i32* %1, align 4
  br label %bb5

bb5:                                              ; preds = %bb3, %bb4, %bb1
  %2 = load i32, i32* %1, align 4
  ret i32 %2
}

!2 = !{i8 -1, i8 2}
!3 = !{}
```

Optimizes to this slightly suboptimal IR:
```llvm
define i32 @src(i8 noundef %0) local_unnamed_addr #0 {
  %switch.tableidx = add i8 %0, 1
  %switch.idx.cast = zext i8 %switch.tableidx to i32
  %switch.offset = add nsw i32 %switch.idx.cast, -1
  ret i32 %switch.offset
}
```

But as Alive confirms, it could just be a `sext`:
```llvm
define i32 @tgt(i8 noundef %0) {
%start:
  %1 = sext i8 noundef %0 to i32
  ret i32 %1
}
// Transformation seems to be correct!
```


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy1Vktv4zYQ_jXyhYghUZIfBx2cpAV6ClDspaeAIscSU4r0kpSTza_vkJJtWetNW2Q3cGxK_Djzcd61Ed-qp4Mn3jLt9sZ2zEujiWvNq9QNcX1tDl52TBHeWwvaEwuuV54gyNte_53kO5LkD633B4frhP6OH6WO3bIxojbKL41t8NU7_r-8rI78WH7Nk_y3JH1M0t1OySNQIqAz2iGHqNy3DAm1QA7WHIwDMWcnHeEG2XB_UzuLQpeRxKCcw8ig3e1M-3xW_2RlIzVerjNeHlE4XhneWHdQQKQm12Ib6du-XnLT4YPtnb9TTDfjGn-kcz04XGzLPMtvMgvIG3YRx79ga9cbjsTIwGz4_oJG2BulBmdwIyCIGgCrdPiEaw6vBOylRuI5JUmROssTupEbok2vcYsktEwTuiXJ-n7AO8-sPwskAZAh50fCUCNnQVBCH_BJNpoUE5SxAuwVcnMBZieg88Yim82o-CGidufzN07g1jONcpVhYpT641O4TGiGodFAWNDxxeW-6IUTl1fpeTuSeY5IxWpQ4bGuUWd5f4KSgLrLZpD8ajud7RZXu_Ozl_uVj1PvouIQJf_rL8nvMS1AuGgmFD84cVTQawuMt6xWcK0o_8mKRt9ipA2WiqESvZTdCJnaTs1RXlMrfhm19JPMsl_G7LM2Kz_PLMREzJcYvqfVNBWnmThUgo8ZW_BD7cGjI931VbyHHB3VZ1iEzmmGC3qBYtZOQJf3p3o3lfgUepN8B0e8wY6BfcEhp9arb9PO9cefP6FqhjqnnnutWQfimQmBBZDm6aWaRpsNdWbpQwZK8TbUSCGmVTD7Ho7IJWfOR_g7vPkRP5eGlwwu-O682e8d-LMy7V5PjpgpCPrvshsOuxI0d94ty9_3njBHYv_GxqT30nYuOtPjY68EecFeR2ogjOBRh5cKEv6zH3zj_6V7nbPrRgNzow2nh2fWm1w-m1849mryZTYSAXQxzmo4Tx80-8BEC1HlYptv2cJLr6AKZohmxgUyC5MUN43G8BXBlPC1xxFEhRELlVxstuitqj6YRKIFh587HJheIq_LMFIW5SpbtNU-LzdZQTkXa15QYMBzugLYFukqZek6XcRq46rQCSnVgCEUROAau9ZCVjSlNM3RWJu8LLbLNM23sE8pK0oK-w1Fl0HHpDpPXQtbRUp13zjcVNJ5d9lkzmHtAIjqUD7rfWts5bjxvuPdIuquIvd_AIRn684">