[clang] [llvm] [InstCombine] Infer disjoint flag on Or instructions. (PR #72912)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 4 10:56:33 PST 2023


topperc wrote:

> Here's a simple-ish example:
> 
> ```llvm
> ; Transforms/InstCombine/add.ll
> 
> define i5 @zext_sext_not(i4 %x) {
>   %zx = zext i4 %x to i5
>   %notx = xor i4 %x, 15
>   %snotx = sext i4 %notx to i5
>   %r = add i5 %zx, %snotx
>   ret i5 %r
> }
> =>
> define i5 @zext_sext_not(i4 %x) {
>   %zx = zext i4 %x to i5
>   %notx = xor i4 %x, 15
>   %snotx = sext i4 %notx to i5
>   %r = or disjoint i5 %zx, %snotx
>   ret i5 %r
> }
> Transformation doesn't verify! (unsound)
> ERROR: Target is more poisonous than source
> 
> Example:
> i4 %x = undef
> 
> Source:
> i5 %zx = #x00 (0)	[based on undef value]
> i4 %notx = #xf (15, -1)	[based on undef value]
> i5 %snotx = #x1f (31, -1)
> i5 %r = #x1f (31, -1)
> 
> Target:
> i5 %zx = #x0f (15)
> i4 %notx = #xf (15, -1)
> i5 %snotx = #x1f (31, -1)
> i5 %r = poison
> Source value: #x1f (31, -1)
> Target value: poison
> ```
> 
> Essentially the code doesn't take into consideration that a same register may have different values when it is undef.

Looks like this is caused by the checks in `haveNoCommonBitsSetSpecialCases`.

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


More information about the llvm-commits mailing list