llvm / llvm-project

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

Wrong vector select folding on undef values by InstCombine #98433

Open bonjune opened 2 months ago

bonjune commented 2 months ago

Transformation of the miscompilation: select Cond, Y, (shuf_sel X, Y) --> shuf_sel (select Cond, Y, X), Y (The latter one in the following source code listing)

https://github.com/llvm/llvm-project/blob/7eae9bb856135136cddc4208a2b1546e9db44c9c/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp#L2616-L2629

Alive2 report: https://alive2.llvm.org/ce/z/EixYHA

----------------------------------------
define <4 x i8> @fun0(<4 x i8> %val1, i1 %val2) {
entry:
  %val3 = shufflevector <4 x i8> { 0, 1, 2, 3 }, <4 x i8> %val1, 0, 5, 2, 3
  %val4 = select i1 %val2, <4 x i8> %val1, <4 x i8> %val3
  ret <4 x i8> %val4
}
=>
define <4 x i8> @fun0(<4 x i8> %val1, i1 %val2) {
entry:
  %sel = select i1 %val2, <4 x i8> %val1, <4 x i8> { 0, poison, 2, 3 }
  %val4 = shufflevector <4 x i8> %sel, <4 x i8> %val1, 0, 5, 2, 3
  ret <4 x i8> %val4
}
Transformation doesn't verify!

ERROR: Target's return value is more undefined

Example:
<4 x i8> %val1 = < #x00 (0), poison, #x00 (0), undef >
i1 %val2 = undef

Source:
<4 x i8> %val3 = < #x00 (0), poison, #x02 (2), #x03 (3) >
<4 x i8> %val4 = < #x00 (0), poison, #x02 (2), #x03 (3) >

Target:
<4 x i8> %sel = < #x00 (0), poison, #x02 (2), #x03 (3) >
<4 x i8> %val4 = < #x00 (0), poison, #x02 (2), #x00 (0) >
Source value: < #x00 (0), poison, #x02 (2), #x03 (3) >
Target value: < #x00 (0), poison, #x02 (2), #x00 (0) >

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
medievalghoul commented 1 month ago

Can i be assigned with this?

medievalghoul commented 1 month ago

If it possible to assign a default value to the args, would that be a practical approach to solving this miscompilation?