[llvm] [InstCombine] Fold patterns which uses <2N x iM> type for comparisons on <N x i2M> vector types (PR #184328)

Fuad Ismail via llvm-commits llvm-commits at lists.llvm.org
Sun May 10 07:59:47 PDT 2026


================

----------------
fuad1502 wrote:

Hi @cardigan1008, I took some time to look at this problem, and it seems to be weirder than I initially thought...

We basically have two "source" patterns, let's call it A and B:

A:
```
define <4 x i32> @a(<4 x i32> %a, <4 x i32> %b) {
  %cmp = icmp eq <4 x i32> %a, %b
  %sext = sext <4 x i1> %cmp to <4 x i32>
  %shuffle = shufflevector <4 x i32> %sext, <4 x i32> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
  %select = and <4 x i32> %sext, %shuffle
  ret <4 x i32> %select
}
```

B:
```
define <4 x i32> @b(<4 x i32> %a, <4 x i32> %b) {
  %cmp = icmp eq <4 x i32> %a, %b
  %sext = sext <4 x i1> %cmp to <4 x i32>
  %shuffle = shufflevector <4 x i32> %sext, <4 x i32> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
  %select = select <4 x i1> %cmp, <4 x i32> %shuffle, <4 x i32> zeroinitializer
  ret <4 x i32> %select
}
```

We want both to be simplified to C:
```
define <4 x i32> @c(<4 x i32> %a, <4 x i32> %b) {
  %1 = bitcast <4 x i32> %a to <2 x i64>
  %2 = bitcast <4 x i32> %b to <2 x i64>
  %3 = icmp eq <2 x i64> %1, %2
  %4 = sext <2 x i1> %3 to <2 x i64>
  %select = bitcast <2 x i64> %4 to <4 x i32>
  ret <4 x i32> %select
}
```

But from this alive test: https://alive2.llvm.org/ce/z/2SYzbJ
- A transform to B is correct
- A transform to C is correct
- But, B transform to C is incorrect

I realize that it's because, B transform to A is incorrect: https://alive2.llvm.org/ce/z/4_T38F

I assumed that if A is transformed to B (which the compiler does), A should be "equivalent" to B.

I understand that Alive does not report A -> B is incorrect because the output is not "more" poisonous, but if the two are not equivalent, we should not do the transform right? I am new to this poison concept, so please CMIIW

I think the optimization misses this because it uses a flag `IsLogical` to determine whether it is safe to perform the transform without introducing `freeze` instruction, but it does not take into account vector logical operation..

Should I open up an issue for this and maybe try opening up a PR? CC @RKSimon

Note: all of this wasn't detected at first because I always add the `noundef` attribute.

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


More information about the llvm-commits mailing list