[llvm] [InstCombine] fold icmp of select with constants and invertible op (PR #147182)

Acthinks Yang via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 23 02:16:42 PDT 2025


Acthinks wrote:

> > > We can simply extend `foldICmpEqualityWithOffset` to handle the motivating case.
> > 
> > 
> > It seems that we cannot simply extend foldICmpEqualityWithOffset to handle shift operations and bit operations that require Op0 and Op1 to satisfy certain properties at the same time. For example, Shl nsw/nuw, AShr exact. The proof is given below: https://alive2.llvm.org/ce/z/NKvGtR
> > ```
> > define i1 @src_shl_nsw_eq(i8 %a, i1 %cond) {
> >   %a_shl = shl nsw i8 %a, 3
> >   %sel = select i1 %cond, i8 4, i8 16
> >   %cmp = icmp eq i8 %a_shl, %sel
> >   ret i1 %cmp
> > }
> > 
> > define i1 @tgt_shl_nsw_eq(i8 %a, i1 %cond) {
> >   %1 = select i1 %cond, i8 0, i8 2
> >   %cmp = icmp eq i8 %a, %1
> >   ret i1 %cmp
> > }
> > ```
> > 
> > 
> >     
> >       
> >     
> > 
> >       
> >     
> > 
> >     
> >   
> > In the actual processing flow of instcombine, it is captured by foldSelectICmp in advance, so the above code will not be optimized out, but this seems unsafe. Actual optimization results:
> > ```
> > define i1 @shl_nsw_eq(i8 %a, i1 %cond) {
> >   %cmp1 = icmp eq i8 %a, 2
> >   %not.cond = xor i1 %cond, true
> >   %cmp = select i1 %not.cond, i1 %cmp1, i1 false
> >   ret i1 %cmp
> > }
> > ```
> 
> Yeah, we need an extra check for right shifts with the `exact` flag. Can we start with handling constant shamts and checking if the right shift doesn't produce poison?

I haven't found a suitable implementation based on foldICmpEqualityWithOffset. A lot of judgment logic needs to be added to the shift class, and the original op and flag need to be kept to determine whether the simplifyBinOp result is available. Is this in line with expectations?

https://github.com/llvm/llvm-project/pull/147182


More information about the llvm-commits mailing list