<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/87011>87011</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[SLP] Missing sign extension of demoted type before zero extension
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
patrick-rivos
</td>
</tr>
</table>
<pre>
LLVM IR:
```llvm ir
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"
@h = global [16 x i64] zeroinitializer
@.str = constant [5 x i8] c"%lX\0A\00"
define i32 @main() #0 {
entry:
%sext.0 = sext i8 0 to i32
%sext.1 = sext i8 0 to i32
%lshr.0 = lshr i32 0, %sext.0
%lshr.1 = lshr i32 0, %sext.1
%or.0 = or i32 %lshr.0, -1
%or.1 = or i32 %lshr.1, 0
%zext.0 = zext i32 %or.0 to i64
%zext.1 = zext i32 %or.1 to i64
store i64 %zext.0, ptr @h, align 8
store i64 %zext.1, ptr getelementptr inbounds ([16 x i64], ptr @h, i64 0, i64 1), align 8
%0 = load i64, ptr @h, align 8
%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %0)
ret i32 0
}
declare i32 @printf(ptr, ...)
attributes #0 = { "target-features"="+64bit,+a,+v" }
```
SLP pass result:
``` llvm ir
; ModuleID = 'optimized.bc'
source_filename = "lto-works-reduced.ll"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"
@h = global [16 x i64] zeroinitializer
@.str = constant [5 x i8] c"%lX\0A\00"
define i32 @main() #0 {
entry:
store <2 x i64> <i64 1, i64 0>, ptr @h, align 8
%0 = load i64, ptr @h, align 8
%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %0)
ret i32 0
}
declare i32 @printf(ptr, ...)
attributes #0 = { "target-features"="+64bit,+a,+v" }
```
Expected output: `FFFFFFFF`
SLP output: `1`
DemandedBits debug log:
```
DemandedBits: Root: store i64 %zext.0, ptr @h, align 8
DemandedBits: Root: store i64 %zext.1, ptr getelementptr inbounds ([16 x i64], ptr @h, i64 0, i64 1), align 8
DemandedBits: Root: %call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %0)
DemandedBits: Root: ret i32 0
DemandedBits: Visiting: %call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %0) Alive Out: 0x0
DemandedBits: Visiting: %0 = load i64, ptr @h, align 8 Alive Out: 0xffffffffffffffff
DemandedBits: Visiting: %zext.1 = zext i32 %or.1 to i64 Alive Out: 0xffffffffffffffff
DemandedBits: Visiting: %or.1 = or i32 %lshr.1, 0 Alive Out: 0xffffffff
DemandedBits: Visiting: %lshr.1 = lshr i32 0, %sext.1 Alive Out: 0xffffffff
DemandedBits: Visiting: %sext.1 = sext i8 0 to i32 Alive Out: 0xffffffff
DemandedBits: Visiting: %zext.0 = zext i32 %or.0 to i64 Alive Out: 0xffffffffffffffff
DemandedBits: Visiting: %or.0 = or i32 %lshr.0, -1 Alive Out: 0xffffffff
DemandedBits: Visiting: %lshr.0 = lshr i32 0, %sext.0 Alive Out: 0x0
DemandedBits: Visiting: %sext.0 = sext i8 0 to i32 Alive Out: 0x0
```
What's happening:
```
[0, 0]
|
sext.{0,1} -> [0, 0]
|
lshr.{0,1} [0, 0] -> [0, 0]
|
or.{0,1} [-1, 0] -> [-1, 0] {-1 is identical to 1 since this reduced to i1}
|
sext.{0,1} i32 -> [1, 0] {ZExt'd the i1 to i64}
```
The SLP pass determines that the MaxBitWidth is 1 and does not sign-extend to i32 before zero extending.
I think these are possible solutions:
1. Sign-extend to the original input datatype before ZExt ops where MaxBitWidth < `op->getSrcTy() bits` and the zext input `!KnownPositive`.
2. Restrict the MaxBitWidth to be at least `zext->getSrcTy() bits` for ops preceding the zext
SLP bug, so @alexey-bataev
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWE1v4zgS_TX0pSBDpCzLPvgQxx2gsQm20RnMLPayoKSyzA1NCiSVOPn1i5JkxR-Jk-7emdMEgS3L9d6rKlaRJUvvVWUQFyxdsnQ1kk3YWLeoZXCqeIicerR-lNvyeXF7-_sdfP3OkisWr1h8xaZx96_14xaU6-4G6SoMUMogtXy2TQCWrIAJgdGWJVcY1Sy5mk7al0gNF1zMWHLFxSwyieju3dM9IY5og1O1xj2lU754nE6ixjwY-2QirUyziyrTDLD-dRJvWkylbS41sHTJp7ADkk9X8ILOKqOCklq9oBswYx9cCyus8UGaQMCUcDOCFaQiUv0vll7HV_QSn-iWuFYGQSUC2CTeSmUYhTQHJpIYWLbszNAE9zykFYCJ1OMujONWnC5BzSCGYInq1IpfsDqw1X7jeka6bJ2Kmbh-VTs15heM-Rm_3bPbznyQJFjEjy35W5acLOMz4pfXVLy0QXaQVo9inU5OjflbxvzIeA_xwTqk269K5EVNCz-JN3QttaoMzN5H8D2iwoAat2gCfVImt40pPdCaHxXcqQKRxfsLzsT8TPYgwn4JrSxbtkvOHqAKqXULDFJpaD91qZnVwRFwPB63hTmJa6dMWHffQN8Fe-dIn_zriR2GvjQ6vWx1XP2Flm4o_0PeV8VDgAzBqbwJ6PsGoS7PltTpXftHa5Shceipz5JV23_L6SRXgYlrJpaye3tkQsCrM_tt6lDq_vYb1NJ7cOgbHc73NDja1FiyhDtbNhq_rvrNJ7N1UFv1guU4L5jIOkNvG1fgf9ZKo5HbYaPSwUZP1j34yGHZFFiOtT7d2v7eMX9-x-yakiXXovcx-UKf-n7ad1jy5YPe_rH2-rux3misL7sai4Al2CbUDTUWsGl80_8NxtR_Rxb8hGeFW2lKLJcqeCgxbyrQtjrv03NrIvxubUv84xv8jzD9BRv_--78SbX3vuBJTZ4a_q68CspUf5J3cKXVI8I_u4KJd5_14lP9fEq-Pvn7pNbHw8f_SejyBPWeyCfJP579flHgwtT6i8wfj4q_vgAfj7o_H8SnxvSf6ITLDxTvEL65vf-xkYGJzMNG1jWajv9t-3QZdwN92p8XwLLrfkoiZ1jWGnCWrSBqD-wLiDYth4hD44_h9gwc8QE9wA_usWwZcVAeVIkmqEJqShYHr0yBEDaKJsd2kmuTyIdD8UKQlOpB60jq3192lNUSwgZBDU8qFw_a3zYIwxRbYkC3VQY9hI0MLc-d3C1V-EOVYUOBcJCmhNKiB2MD0EN_hLuAptyXQY5rOuFotoPuG2Wq8aHmV4rcPBC9R6ARpLbeq1wjeKuboKzxQz3wMdwfi5BX1qlKGalBmbrpht7wXONenDIBtvbwtEF3HANLrmlQsDWlsMJw74rfnvvpMKein8ZtiKTSdX-rQGkT_B807X6z1BKPyKZxH5YYw3f0waniPGfBQo4gA2iUvuUh1gvia-ta12uHBVLuBldOnzzypqLl95YOIqlxh89RLoPEx1G5SMp5MpcjXPCM8-lUTNNstFmUySSdzNLZWqzzdC55nM-LeVFykUue8SIdqYWIxSROxEzwNE6zcble55NsnsQySSRiyiYxbqXSY3qyGVtXjZT3DS5mWcz5SMsctW9_BBLC4BO0X9IgmK5GbkGYKG8qzyaxVj74V5aggm5_Pbq__Ub1fKe8p-Cpwro68soasGsocWtpNDxc8NdqI6tR4_RiE0LdlpG4YeKmUmHT5OPCbpm4IdH-Laqd_S8WgYmb1lXPxE0byv8CAAD__3dJUjo">