[llvm] [AMDGPU] Use first operand of zext to test first bit zero (PR #217195)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 1 16:49:16 PDT 2026
Shoreshen wrote:
> @Shoreshen you might want to reply my previous comment to give other ideas what's going on here.
Hi @shiltian for some code like
```c++
unsigned base, offset;
char* ptr;
unsigned addr = base + offset;
out = ptr[addr]
```
Clang may generate llvm ir like the following:
```llvm
...
%idxprom = zext i32 %mul34 to i64
%arrayidx = getelementptr inbounds nuw i8, ptr addrspace(1) %input.coerce, i64 %idxprom
%9 = load i8, ptr addrspace(1) %arrayidx, align 1, !tbaa !13
...
```
Hence the DAG:
```mlir
t8: i64 = zero_extend # D:1 t6
t9: i64 = ptradd # D:1 t7, t8
t12: f32,ch = load<(load (s32) from %ir.addr, addrspace 1)> # D:1 t0, t9, poison:i64
```
With `Op` is `t8` , in the function `matchExtFromI32orI32` we can see:
1. `Op.getOpcode() = ISD::ZERO_EXTEND`
2. `DAG->SignBitIsZero(Op)` is true since `Op` is zext.
3. `Op.getOperand(0).getValueType() == MVT::i32`
Thus `matchExtFromI32orI32` will return `Op.getOperand(0)` as instruction offset and creating asm like `global_load_b32 v0, base, offset`.
However, for gfx1250, the offset is signed, which means if bit 31 is set, it will trying to fetch the negative offset according to base.
This conflict with the semantic of cpp and llvm ir, and the key is `DAG->SignBitIsZero(Op)` is testing a zext value.
Thus if we want to use `t6` as offset, we need to test `t6`'s highest bit instead of `t8`
https://github.com/llvm/llvm-project/pull/217195
More information about the llvm-commits
mailing list