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

Reply via email to