llvm / llvm/llvm-project

[FunctionAttrs] addNoUndefAttrs infers noundef on return without accounting for nofpclass poison

Open
#200,245 1 comment 0 reactions 0 assignees View on GitHub
generated by fuzzer llvm:transforms
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/LsEUem

**Description**

FunctionAttrs' `addNoUndefAttrs` adds `noundef` to a function's return value by proving all return paths produce non-poison values (all inputs are `noundef`, all operations propagate non-poison). However, it does not account for the fact that a `nofpclass(...)` attribute on the return can introduce poison.

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

```llvm
declare nofpclass(nan inf zero psub norm) half @returns_nsub()

define nofpclass(nsub) half @ret_nonsub__fadd_self__nonsub(i1 noundef %cond, half noundef %unknown) {
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %nsub, half %unknown
%add = fadd half %select, %select
ret half %add
}
```

**Output**

```llvm

----------------------------------------
declare half @returns_nsub() nofpclass(1007)

define half @ret_nonsub__fadd_self__nonsub(i1 noundef %cond, half noundef %unknown) nofpclass(16) {
#0:
%nsub = call half @returns_nsub() noundef nofpclass(1007)
%select = select i1 noundef %cond, half %nsub, half noundef %unknown
%add = fadd half %select, %select
ret half %add
}
=>
declare half @returns_nsub() nofpclass(1007)

define half @ret_nonsub__fadd_self__nonsub(i1 noundef %cond, half noundef %unknown) noundef nofpclass(16) {
#0:
%nsub = call half @returns_nsub() noundef nofpclass(1007)
%select = select i1 noundef %cond, half %nsub, half noundef %unknown
%add = fadd half %select, %select
ret half %add
}
Transformation doesn't verify!

ERROR: Source is more defined than target

Example:
i1 noundef %cond = #x0 (0)
half noundef %unknown = #x8040 (-0.000003814697?)

Source:
half %nsub = #x8004 (-0.000000238418?)
half %select = #x8040 (-0.000003814697?)
half %add = #x8080 (-0.000007629394?)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: #x0
Block 1 > size: 0 align: 1 alloc type: 0 alive: true address: #x4

Target:
half %nsub = #x8004 (-0.000000238418?)
half %select = #x8040 (-0.000003814697?)
half %add = #x8080 (-0.000007629394?)
half return = UB triggered!

TARGET MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: #x0
Block 1 > size: 0 align: 1 alloc type: 0 alive: true address: #x4

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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.