llvm / llvm/llvm-project

[VectorCombine] or disjoint is scalarized across bitcast while preserving the disjoint flag

Open
#199,783 0 comments 0 reactions 0 assignees View on GitHub
confirmed llvm:vectorcombine miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

**Fuzzer Generated Test**
**Reproducer**

https://alive2.llvm.org/ce/z/4o_-2i

**Description**

VectorCombine rewrites `or disjoint <2 x i32> (bitcast i64 %a), C` as `bitcast (or disjoint i64 %a, C')`, keeping the `disjoint` flag on the scalar op.

**Steps to reproduce**
- Minimized test case, `input.ll`

```llvm
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"

define <2 x i32> @f(i64) {
%2 = bitcast i64 %0 to <2 x i32>
%3 = or disjoint <2 x i32> %2, splat (i32 1)
ret <2 x i32> %3
}
```

**Output**

```llvm
----------------------------------------
define <2 x i32> @f(i64 %#0) {
#1:
%#2 = bitcast i64 %#0 to <2 x i32>
%#3 = or disjoint <2 x i32> %#2, { 1, 1 }
ret <2 x i32> %#3
}
=>
define <2 x i32> @f(i64 %#0) {
#1:
%.inner = or disjoint i64 %#0, 4294967297
%#2 = bitcast i64 %.inner to <2 x i32>
ret <2 x i32> %#2
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
i64 %#0 = #x0000000000000001 (1)

Source:
<2 x i32> %#2 = < #x00000001 (1), #x00000000 (0) >
<2 x i32> %#3 = < poison, #x00000001 (1) >

Target:
i64 %.inner = poison
<2 x i32> %#2 = < poison, poison >
Source value: < poison, #x00000001 (1) >
Target value: < poison, poison >

Summary:
0 correct transformations
1 incorrect transformations
0 failed-to-prove transformations
0 Alive2 errors
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the minimized input.ll case with the VectorCombine transformation and compare it with the Alive2 reproducer linked in the issue. Trace the rewrite that moves the vector or disjoint operation across the bitcast; done means the transformed IR no longer preserves an invalid disjoint flag or becomes more poisonous than the source.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.