<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/124841>124841</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Unnecessary sext when optimizing a switch on riscv
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
WaffleLapkin
</td>
</tr>
</table>
<pre>
Given this llvm-ir (output of rustc, see details in https://github.com/rust-lang/rust/issues/136216):
```llvm
define dso_local noundef range(i8 1, 9) i8 @opposite_match(i8 noundef zeroext range(i8 1, 9) %0) unnamed_addr {
start:
%_0 = alloca [1 x i8], align 1
%x = alloca [1 x i8], align 1
store i8 %0, ptr %x, align 1
%1 = load i8, ptr %x, align 1
%_2 = zext i8 %1 to i32
switch i32 %_2, label %bb1 [
i32 1, label %bb5
i32 2, label %bb4
i32 4, label %bb3
i32 8, label %bb2
]
bb1: ; preds = %start
unreachable
bb5: ; preds = %start
store i8 4, ptr %_0, align 1
br label %bb6
bb4: ; preds = %start
store i8 8, ptr %_0, align 1
br label %bb6
bb3: ; preds = %start
store i8 1, ptr %_0, align 1
br label %bb6
bb2: ; preds = %start
store i8 2, ptr %_0, align 1
br label %bb6
bb6: ; preds = %bb2, %bb3, %bb4, %bb5
%2 = load i8, ptr %_0, align 1
ret i8 %2
}
```
llvm currently produces this:
```asm
opposite_match:
addi a0, a0, -1
slli a0, a0, 24
srai a0, a0, 24
lui a1, %hi(.Lswitch.table.opposite_match)
addi a1, a1, %lo(.Lswitch.table.opposite_match)
add a0, a1, a0
lbu a0, 0(a0)
ret
.Lswitch.table.opposite_match:
.ascii "\004\b\004\001\004\004\004\002"
```
`slli` + `srai` is a `i8`->`i32` sign extension, but it's not needed here -- `1 <= a0 <= 8` originally (from the `range` attribute) and after subtracting `1` it's obviously `0 <= a0 <= 7`, so sign extension is the same as zero extension (and thus could be a noop in this case).
`sext` is added in an `InstCombinePass`:
```diff
define dso_local noundef range(i8 1, 9) i8 @opposite_match(i8 noundef zeroext range(i8 1, 9) %0) unnamed_addr {
start:
- %switch.tableidx = sub nsw i8 %0, 1
- %switch.gep = getelementptr inbounds [8 x i8], ptr @switch.table.opposite_match, i32 0, i8 %switch.tableidx
+ %switch.tableidx = add nsw i8 %0, -1
+ %1 = sext i8 %switch.tableidx to i32
+ %switch.gep = getelementptr inbounds [8 x i8], ptr @switch.table.opposite_match, i32 0, i32 %1
%switch.load = load i8, ptr %switch.gep, align 1
ret i8 %switch.load
}
```
[Godbolt link](https://godbolt.org/z/jdE4vYPYa) (and [godbolt link with more versions of the function, which I was experimenting with](https://godbolt.org/z/vGjGT9oW1)).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMV09v2zoM_zTKhUggy3ZiH3Jo0rUYsMMO72HYqZBtJtamSIYkp38-_QPlJHXdrugb9oAXBIkMkj_-SFkkJb1Xe4O4ZvmG5dcz2YfWuvU3udtp_CK7n8rMKts8rm_VEQ2EVnnQ-niYKwdMFLYPXR_A7sD1PtRMbMEjQoNBKu1BGWhD6DxLr5i4YeJmr0LbV4vaHpi4IZO5lmZ_WjNxo7zv0TNxk6RLkSyZKMmUX7ElH77km_GrBnfKIDTe3mlbSw3G9qbBHThp9shEoQpIiE3JRAmqAJZx23XWq4B3BxnqdtA5mz2hs_gQ3jZnIuf03xsjD9jcyaZxwFYbxq98kC4MFIH07jiw9BqkJlbA8k0CD6AKll8TmtRqbyAhZSbyhw-qgg_WYQwiEtlCF1wEmCoykScRVFvZENb7unciKj9R4AN6AsGCSsXg9l6FuqXHQZkQtKxQ02NVJcQ5KkLUSSbyfCSb2mYjWTaRpSQjQTERDKwoP5zyXVUJSyPKxz8s3UDnsPExcCbyYf8ItzcOZd3KSuMZPyf8d0wu-5KNEn3Hp5mu3DiK5Rk9-4PsL0yK32GSfjTO5HfQxZ_cpQsV8TtUlm8GShTF9vzynVfZZZWfz4v4xdl67d_h-UTRS8tW1-MSxvgVVTGoe-fQBP0InbNNX6OP5fVU8EYG0lPJm5SvU80ZPrJpVPwfmMTfeTJS8FqrF1KRjaVOvjJ_oaB7NfhJTllpFRPF4stQIhaBTs1iWl_LtwhGgAuMtv8aBkZEkxPdEdGqPwk5EwWtxuYOw5Da912-SO1C-lopYEKwfMt5xvJtdVlxnozW419BBi83fXiknWBLDkxsgB6djI_Kg6RnVbAln7P0E61TQSJq0IAPAY1X1lBsVR9ABSZWHowNYBAbbKBFhzCfEwp1gW3sLvy8IlywTu2VkVo_UvPeOXuA0CJZDI1vyUGG4FTVB6SOJ00DchfQge-r4GQdlNlHB5HzQMFWR2V7T5hLzl97XlH4NBjYSSgUNLn38oAgfWzCIyltoGkgtL2H2va6gQpBgrG2o8EijiK19ER08ZxefAjnfDaUFWVAGmL22fiwtYdKGfwqvSdSr05ao3Y72vv_y3gBo_liHmvQ-L1VzTBC-L4C4-_HE0IyNdhjF3X3GFDjAU2g4qVMRQw9tfJiPH7Eypbxdw_mNnbp6G7wPOFGiRWbX7KmszxhHUvW2WaYZPzzcDIFuYwqEy__cajDOHQqrs9eY1t4uz8885r2iVGjGMHE-fBVz6Bvvrm1TWV1AK3MzxhAMRmwB_nCOpqqn5i4-dF8yo7fv36Xw7sWzxTLN_sRENyr0MKBWusRHR0-TyM9nc1db-pwKjv3rapb-Az30gM-dOgUJZcqAtl_jM3x9sftX6X9llBlFuVi1qzTpkxLOcN1skoLXpbpajVr13VZ7oQoRZauhCjzukxlVYmsqdIsKepVPVNrwUXOE1GIRIh8tUhRyGW-LEuZJrLmnGUcD1LpBXVbojCLt4t1IrIiS2ZxQPDx3iOEwXuI0ljnr2duHS85Vb_3LONa-eCfYYIKGtd_G4M1ei_d4_CW3rdowHZBHdQTJUWeJ2hrwClfH2e90-t37kPxbjP8zTtnf2D98ko08D6uxT8BAAD___mR6Uw">