| Issue |
114354
|
| Summary |
[InstCombine] wrong folding of `(lshr (add (zext X), (zext Y)), K)` for undefined inputs
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
bongjunj
|
https://github.com/llvm/llvm-project/blob/6bf214b7c6d74ec581bc52a9142756a1d1df6df0/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp#L964-L978
Alive2 report: https://alive2.llvm.org/ce/z/18Sfgb
```llvm
----------------------------------------
define i4 @not_bool_add_lshr.2(i2 %a, i2 %b) {
#0:
%#1 = mul i2 %a, 3
%zext.a = zext i2 %#1 to i4
%zext.b = zext i2 %b to i4
%add = add nsw i4 %zext.a, %zext.b
%lshr = lshr i4 %add, 2
ret i4 %lshr
}
=>
define i4 @not_bool_add_lshr.2(i2 %a, i2 %b) {
#0:
%#1 = sub i2 0, %a
%add.narrowed = sub i2 %b, %a
%add.narrowed.overflow = icmp ult i2 %add.narrowed, %#1
%lshr = zext i1 %add.narrowed.overflow to i4
ret i4 %lshr
}
Transformation doesn't verify!
ERROR: Target's return value is more undefined
Example:
i2 %a = undef
i2 %b = #x0 (0)
Source:
i2 %#1 = #x0 (0) [based on undef value]
i4 %zext.a = #x0 (0)
i4 %zext.b = #x0 (0)
i4 %add = #x0 (0)
i4 %lshr = #x0 (0)
Target:
i2 %#1 = #x1 (1)
i2 %add.narrowed = #x0 (0)
i1 %add.narrowed.overflow = #x1 (1)
i4 %lshr = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)
----------------------------------------
define i64 @lshr_16_to_64_add_zext_basic.2(i16 %a, i16 %b) {
#0:
%zext.a = zext i16 %a to i64
%#1 = mul i16 %a, %b
%zext.b = zext i16 %#1 to i64
%add = add i64 %zext.a, %zext.b
%lshr = lshr i64 %add, 16
ret i64 %lshr
}
=>
define i64 @lshr_16_to_64_add_zext_basic.2(i16 %a, i16 %b) {
#0:
%#1 = add i16 %b, 1
%add.narrowed = mul i16 %a, %#1
%add.narrowed.overflow = icmp ult i16 %add.narrowed, %a
%lshr = zext i1 %add.narrowed.overflow to i64
ret i64 %lshr
}
Transformation doesn't verify!
ERROR: Target's return value is more undefined
Example:
i16 %a = undef
i16 %b = #x0000 (0)
Source:
i64 %zext.a = #x0000000000000000 (0) [based on undef value]
i16 %#1 = #x0000 (0)
i64 %zext.b = #x0000000000000000 (0)
i64 %add = #x0000000000000000 (0)
i64 %lshr = #x0000000000000000 (0)
Target:
i16 %#1 = #x0001 (1)
i16 %add.narrowed = #x0000 (0)
i1 %add.narrowed.overflow = #x1 (1)
i64 %lshr = #x0000000000000001 (1)
Source value: #x0000000000000000 (0)
Target value: #x0000000000000001 (1)
----------------------------------------
define i32 @lshr_32_add_zext_trunc.2(i32 %a, i32 %b) {
#0:
%zext.a = zext i32 %a to i64
%zext.b = zext i32 %b to i64
%add = add nsw nuw i64 %zext.a, %zext.b
%#1 = add i64 %zext.b, %add
%trunc.add = trunc i64 %#1 to i32
%shr = lshr i64 %add, 32
%trunc.shr = trunc i64 %shr to i32
%ret = add nuw i32 %trunc.add, %trunc.shr
ret i32 %ret
}
=>
define i32 @lshr_32_add_zext_trunc.2(i32 %a, i32 %b) {
#0:
%add.narrowed = add i32 %a, %b
%add.narrowed.overflow = icmp ult i32 %add.narrowed, %a
%trunc.add = add i32 %b, %add.narrowed
%trunc.shr = zext i1 %add.narrowed.overflow to i32
%ret = add nuw i32 %trunc.add, %trunc.shr
ret i32 %ret
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
i32 %a = undef
i32 %b = #x00000000 (0)
Source:
i64 %zext.a = #x0000000000000000 (0) [based on undef value]
i64 %zext.b = #x0000000000000000 (0)
i64 %add = #x0000000000000000 (0)
i64 %#1 = #x0000000000000000 (0)
i32 %trunc.add = #x00000000 (0)
i64 %shr = #x0000000000000000 (0)
i32 %trunc.shr = #x00000000 (0)
i32 %ret = #x00000000 (0)
Target:
i32 %add.narrowed = #x00000000 (0)
i1 %add.narrowed.overflow = #x1 (1)
i32 %trunc.add = #xffffffff (4294967295, -1)
i32 %trunc.shr = #x00000001 (1)
i32 %ret = poison
Source value: #x00000000 (0)
Target value: poison
Summary:
0 correct transformations
3 incorrect transformations
0 failed-to-prove transformations
0 Alive2 errors
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs