llvm-project
3b2c3b02 - [AMDGPU] Use first operand of zext to test first bit zero (#217195)

Commit
11 days ago
[AMDGPU] Use first operand of zext to test first bit zero (#217195) Fix AMDGPU SAddr selection for zero-extended 32-bit offsets on targets with signed GVS VOffset. For DAG, function `matchExtFromI32orI32` will return valid value if address can be `Addr:SGPR` + `Signed Offset:VGPR`, and the function is as follow: ```c++ static SDValue matchExtFromI32orI32(SDValue Op, bool IsSigned, const SelectionDAG *DAG) { if (Op.getValueType() == MVT::i32) return Op; if (Op.getOpcode() != (IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND) && Op.getOpcode() != ISD::ANY_EXTEND && !(DAG->SignBitIsZero(Op) && Op.getOpcode() == (IsSigned ? ISD::ZERO_EXTEND : ISD::SIGN_EXTEND))) return SDValue(); SDValue ExtSrc = Op.getOperand(0); return (ExtSrc.getValueType() == MVT::i32) ? ExtSrc : SDValue(); } ``` Assuming: 1. Address is formed by addition, denote `Addr = add BASE, OFFSET` 2. Then `OFFSET` = `Op` under `AMDGPUDAGToDAGISel::SelectGlobalSAddr` calling `matchExtFromI32orI32` 3. `i64 Op = zext i32 Src` which means `i64 OFFSET = zext i32 Src` 4. `Src` some how have the value of `Src = 0x80000000` 5. `IsSigned` is true if we are running under signed offset arch With above assumption, we have: 1. Fail in `Op.getValueType() == MVT::i32` 2. `Op.getOpcode() != ISD::SIGN_EXTEND` 3. `Op.getOpcode() != ISD::ANY_EXTEND` 4. `Op.getOpcode() == ISD::ZERO_EXTEND` and since `Op` is the result of zext, the highest bit of `Op` is zero so `DAG->SignBitIsZero(Op)` is also true 5. `!(DAG->SignBitIsZero(Op) && Op.getOpcode() == ISD::ZERO_EXTEND)` is false Thus, it will pass the if check and return valid `SDValue`, which in the end create instructions such as `(LOAD/STORE_SADDR BASE, (ZEXT Src))` and `Src = 0x80000000`, which is actually addressing `BASE - 0x80000000` Co-authored-by: shore <shorshen@amd.com>
Author
Parents
Loading