LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 42198 - incorrect instcombine fold for icmp sgt
Summary: incorrect instcombine fold for icmp sgt
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Roman Lebedev
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-06-08 15:42 PDT by Nuno Lopes
Modified: 2019-06-09 09:31 PDT (History)
4 users (show)

See Also:
Fixed By Commit(s): 362911


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nuno Lopes 2019-06-08 15:42:02 PDT
The following instcombine rewrite seems incorrect (test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sgt-to-icmp-sgt.ll):


define i1 @cv0_GOOD(i8 %y) {
%0:
  %x = call i8 @gen8()
  %tmp0 = lshr i8 255, %y
  %tmp1 = and i8 %tmp0, %x
  %ret = icmp sgt i8 %x, %tmp1
  ret i1 %ret
}
=>
define i1 @cv0_GOOD(i8 %y) {
%0:
  %x = call i8 @gen8()
  %tmp0 = lshr i8 255, %y
  %1 = icmp sgt i8 %x, %tmp0
  ret i1 %1
}
Transformation doesn't verify!
ERROR: Value mismatch

Example:
i8 %y = #x00 (0)

Source:
i8 %x = #x7f (127, -129)
i8 %tmp0 = #xff (255, -1)
i8 %tmp1 = #x7f (127, -129)
i1 %ret = #x0 (0)

Target:
i8 %x = #x7f (127, -129)
i8 %tmp0 = #xff (255, -1)
i1 %1 = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)
Comment 1 Roman Lebedev 2019-06-09 00:06:46 PDT
Nice! Thank you for reporting!
Really happy that the tool, as it is being expanded,
uncovers yet more and more horrors of all this pattern-matching!

And same for llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sle-to-icmp-sle.ll
So basically all the folds in that group when the comparison predicate is signed.
Comment 2 Sanjay Patel 2019-06-09 05:36:48 PDT
For reference, the commit that introduced this specific test change was:
https://reviews.llvm.org/rL337105

We missed a precondition. Not sure if it's worth using value tracking (isKnownNonZero) to preserve the cases that could still be reduced:

https://rise4fun.com/Alive/5gkT

Pre: C1 != 0
  %tmp0 = lshr i8 255, C1
  %tmp1 = and i8 %tmp0, %x
  %ret = icmp sgt i8 %x, %tmp1
=>
  %tmp0 = lshr i8 255, C1
  %ret = icmp sgt i8 %x, %tmp0
Comment 3 Roman Lebedev 2019-06-09 05:45:40 PDT
(In reply to Sanjay Patel from comment #2)
> For reference, the commit that introduced this specific test change was:
> https://reviews.llvm.org/rL337105
Yep.

> We missed a precondition.
Not so much missed. I did check the original fold with constants,
and then somehow managed to be completely unbothered to check the fold with
the `lshr`, and didn't think of it even.

> Not sure if it's worth using value tracking
> (isKnownNonZero) to preserve the cases that could still be reduced:
Could be done as a new feature.

> https://rise4fun.com/Alive/5gkT
> 
> Pre: C1 != 0
>   %tmp0 = lshr i8 255, C1
>   %tmp1 = and i8 %tmp0, %x
>   %ret = icmp sgt i8 %x, %tmp1
> =>
>   %tmp0 = lshr i8 255, C1
>   %ret = icmp sgt i8 %x, %tmp0
Comment 4 Roman Lebedev 2019-06-09 09:31:34 PDT
Checked other folds there, with other edge-cases (0, -1), everything else seems fine now..
Thanks for the bugreport (: