[PATCH] D78582: [InstCombine] substitute equivalent constant to reduce logic-of-icmps

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 23 02:41:10 PDT 2020


lebedev.ri added a reviewer: nlopes.
lebedev.ri accepted this revision.
lebedev.ri added a comment.
This revision is now accepted and ready to land.

Same preexisting soundness problem as visible in D78430 <https://reviews.llvm.org/D78430>, but other than that LG.



================
Comment at: llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll:155-253
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == null) || (X <= Y) --> X <= Y
 ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 define i1 @ule_or_min(i8* %x, i8* %y)  {
----------------
Likewise with D78430, alive says all these are preexisting miscompiles:
```
----------------------------------------
define i1 @ule_or_min(* %x, * %y) {
%0:
  %cmp = icmp ule * %x, %y
  %cmpeq = icmp eq * %x, null
  %r = or i1 %cmp, %cmpeq
  ret i1 %r
}
=>
define i1 @ule_or_min(* %x, * %y) {
%0:
  %cmp = icmp ule * %x, %y
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=1, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x1 (1)
i1 %r = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 4        alloc type: 0

Target:
i1 %cmp = #x0 (0)
Source value: #x1 (1)
Target value: #x0 (0)


----------------------------------------
define i1 @ule_or_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ule * %x, %y
  %cmpeq = icmp eq * %x, null
  %r = or i1 %cmpeq, %cmp
  ret i1 %r
}
=>
define i1 @ule_or_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ule * %x, %y
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=2, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x1 (1)
i1 %r = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 0        alloc type: 0

Target:
i1 %cmp = #x0 (0)
Source value: #x1 (1)
Target value: #x0 (0)


----------------------------------------
define i1 @ule_swap_or_min(* %x, * %y) {
%0:
  %cmp = icmp uge * %y, %x
  %cmpeq = icmp eq * %x, null
  %r = or i1 %cmp, %cmpeq
  ret i1 %r
}
=>
define i1 @ule_swap_or_min(* %x, * %y) {
%0:
  %cmp = icmp uge * %y, %x
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=2, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x1 (1)
i1 %r = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 4        alloc type: 0
Block 2 >       size: 0 align: 2        alloc type: 0

Target:
i1 %cmp = #x0 (0)
Source value: #x1 (1)
Target value: #x0 (0)


----------------------------------------
define i1 @ule_swap_or_min_commute(* %x, * %y) {
%0:
  %cmp = icmp uge * %y, %x
  %cmpeq = icmp eq * %x, null
  %r = or i1 %cmpeq, %cmp
  ret i1 %r
}
=>
define i1 @ule_swap_or_min_commute(* %x, * %y) {
%0:
  %cmp = icmp uge * %y, %x
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=1, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x1 (1)
i1 %r = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 2        alloc type: 0

Target:
i1 %cmp = #x0 (0)
Source value: #x1 (1)
Target value: #x0 (0)


----------------------------------------
define i1 @ugt_and_not_min(* %x, * %y) {
%0:
  %cmp = icmp ugt * %x, %y
  %cmpeq = icmp ne * %x, null
  %r = and i1 %cmp, %cmpeq
  ret i1 %r
}
=>
define i1 @ugt_and_not_min(* %x, * %y) {
%0:
  %cmp = icmp ugt * %x, %y
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=2, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x0 (0)
i1 %r = #x0 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 2        alloc type: 0

Target:
i1 %cmp = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)


----------------------------------------
define i1 @ugt_and_not_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ugt * %x, %y
  %cmpeq = icmp ne * %x, null
  %r = and i1 %cmpeq, %cmp
  ret i1 %r
}
=>
define i1 @ugt_and_not_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ugt * %x, %y
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=2, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x0 (0)
i1 %r = #x0 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 2        alloc type: 0

Target:
i1 %cmp = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)


----------------------------------------
define i1 @ugt_swap_and_not_min(* %x, * %y) {
%0:
  %cmp = icmp ult * %y, %x
  %cmpeq = icmp ne * %x, null
  %r = and i1 %cmp, %cmpeq
  ret i1 %r
}
=>
define i1 @ugt_swap_and_not_min(* %x, * %y) {
%0:
  %cmp = icmp ult * %y, %x
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=2, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x0 (0)
i1 %r = #x0 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 2        alloc type: 0

Target:
i1 %cmp = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)


----------------------------------------
define i1 @ugt_swap_and_not_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ult * %y, %x
  %cmpeq = icmp ne * %x, null
  %r = and i1 %cmpeq, %cmp
  ret i1 %r
}
=>
define i1 @ugt_swap_and_not_min_commute(* %x, * %y) {
%0:
  %cmp = icmp ult * %y, %x
  ret i1 %cmp
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %x = null
* %y = pointer(non-local, block_id=1, offset=0)

Source:
i1 %cmp = undef
i1 %cmpeq = #x0 (0)
i1 %r = #x0 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 64       alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0
Block 2 >       size: 0 align: 4        alloc type: 0

Target:
i1 %cmp = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)
```


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78582/new/

https://reviews.llvm.org/D78582





More information about the llvm-commits mailing list