[llvm] [InstCombine] Simplify and/or of icmp eq with op replacement (PR #70335)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 2 05:00:17 PDT 2023


mikaelholmen wrote:

> > > @mikaelholmen Thank you! Here is a reduced version:
> > > ```llvm
> > > declare void @barrier()
> > > 
> > > define i1 @test1(i32 %x) {
> > >   %cmp1 = icmp ne i32 %x, 0
> > >   call void @barrier()
> > >   %div = udiv i32 2147483647, %x
> > >   %cmp2 = icmp ugt i32 %x, %div
> > >   %or = or i1 %cmp1, %cmp2
> > >   ret i1 %or
> > > }
> > > ```
> > > 
> > > 
> > >     
> > >       
> > >     
> > > 
> > >       
> > >     
> > > 
> > >     
> > >   
> > > What happens is that we try to evaluate `%cmp2` with `%x==0`, in which case the division is UB and folds to poison. We then fold `or` with a poison operand, resulting in an overall `poison` result.
> > 
> > 
> > But... the `@test1` example is indeed UB in case %x is 0, right? Since the div is always carried out, even if %x is 0, and then the result is used to calculate the return value %or (via icmp and or)? Or what am I missing here?
> > In the original ic.ll example the udiv was avoided if the denominator was 0 and UB was avoided.
> 
> If `%x` is 0 there is indeed UB. But if `%x` is not zero, then the IR is well-defined and will always return true, so the fold to poison is incorrect.

Ah, ye it folded the whole thing to poison regardless of %x. I follow. Thanks!

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


More information about the llvm-commits mailing list