| 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