| Issue |
87011
|
| Summary |
[SLP] Missing sign extension of demoted type before zero extension
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
patrick-rivos
|
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
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs