llvm / llvm/llvm-project

[InstCombine] Unsound masked-xor fold duplicates an operand that may contain undef

Open
#221,883 1 comment 0 reactions 0 assignees View on GitHub
llvm:instcombine miscompilation:undef
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

InstCombine appears to perform an invalid transformation of a masked XOR expression involving `freeze` in following cases.

```llvm
define <2 x i4> @in_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) {
%notmask = xor <2 x i4> %mask, splat (i4 -1)
%n0 = xor <2 x i4> %x, splat (i4 6)
%freeze.ins = freeze <2 x i4> %notmask
%n1 = and <2 x i4> %n0, %freeze.ins
%r = xor <2 x i4> %n1, splat (i4 6)
ret <2 x i4> %r
}
```

But the optimised expression introduces a second use of `%x`. The two uses may observe different values, thus making the target more undefined than the source if `%x` contains `undef`.

```llvm
define <2 x i4> @in_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) local_unnamed_addr #0 {
%mask.fr = freeze <2 x i4> %mask
%n0 = xor <2 x i4> %x, splat (i4 6)
%1 = and <2 x i4> %mask.fr, %n0
%r = xor <2 x i4> %1, %x
ret <2 x i4> %r
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
```

Reproduce: https://alive2.llvm.org/ce/z/Z8mus8

Contributor guide

Open the contributing guide

Research direction

Start with the InstCombine masked-XOR transformation described in the issue and reproduce the failure using the provided LLVM IR and Alive2 link. Trace how the freeze and repeated operand uses are handled. Done means the optimization no longer makes `%x` observe different undef values than in the source expression, with the reproducer covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.