llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.34k stars 11.7k forks source link

[InstCombine] very different results with nearly identical functions with a `select` and `icmp eq` #58275

Open mikebenfield opened 1 year ago

mikebenfield commented 1 year ago

Two nearly identical functions

InstCombine optimizes one of them very well. The other one not so much. Unfortunately I don't have the terminology to describe what's going on better than pointing to that link. Maybe someone else could help me out.

RalfJung commented 1 year ago

Cc @nikic your help with this would be appreciated :)

nikic commented 1 year ago

cc @rotateright Looks like another issue with missing trunc vs and canonicalization for icmps?

rotateright commented 1 year ago

cc @rotateright Looks like another issue with missing trunc vs and canonicalization for icmps?

Yes, I think the fold itself is easy: https://alive2.llvm.org/ce/z/umK_t- ...but it can interfere with other pattern-matching, and we likely have conflicting folds (infinite loop potential) buried in there, so we probably have to untangle some other transforms.

rotateright commented 1 year ago

I looked at this, and it's probably better to try the reverse of what I posted above: https://alive2.llvm.org/ce/z/ZQZ9zb (create a mask op instead of truncating) ...because we already do that for equality predicates, and that works for unsigned preds too.

But then we hit another problem because we chop off the low bit of the mask in the example shown here:

define i1 @myfunction1(i16 %0) local_unnamed_addr #0 {
start:
  %1 = and i16 %0, 254
  %2 = icmp ult i16 %1, 50
  %z.mask = and i16 %0, 255
  %3 = icmp eq i16 %z.mask, 47
  %4 = and i1 %2, %3
  ret i1 %4
}