Issue 182677
Summary [AMDGPU] BFE_I32 ComputeNumSignBits unsigned underflow due to missing `& 0x1f` width mask
Labels backend:AMDGPU
Assignees
Reporter yijan4845
    ## Vulnerable code location(s)

`llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp`: [link](https://github.com/llvm/llvm-project/blob/f1bfed10ad5a5214eab553dbec99fa7dfd604551/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp#L5984)

## Vulnerable code analysis

The `BFE_I32` case in `ComputeNumSignBitsForTargetNode` computes:

```cpp
unsigned SignBits = 32 - Width->getZExtValue() + 1;
```

The width operand is not masked with `& 0x1f`, unlike every other BFE width use in this file:

- DAG combiner, `BFE_I32`: `& 0x1f`
- `computeKnownBitsForTargetNode`, `BFE_I32`): `& 0x1f`
- `ComputeNumSignBitsForTargetNode`, `BFE_U32`: `& 0x1f`

The hardware BFE instruction only uses the low 5 bits of the width field, so user IR can legally pass width values ≥ 32 via `@llvm.amdgcn.sbfe.i32`. When `Width->getZExtValue()` > 33, `32 - Width` underflows as an unsigned operation, producing a huge `SignBits` value. When width == 33, `SignBits` = 0, which violates the `ComputeNumSignBits` contract of returning `[1, BitWidth]`.

## PoC

This can cause assertion failures like: [https://godbolt.org/z/Kr6hbjhaz](https://godbolt.org/z/Kr6hbjhaz)

This can also cause miscompilation because subsequent BFE operations that narrow the value can be incorrectly eliminated: [https://godbolt.org/z/5KnEdborr](https://godbolt.org/z/5KnEdborr)


_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to