[llvm] [GISel] Set more MIFlags when translating GEPs (PR #151708)
Fabian Ritter via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 01:38:22 PDT 2025
================
@@ -1592,9 +1592,19 @@ bool IRTranslator::translateGetElementPtr(const User &U,
Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
- uint32_t Flags = 0;
+ uint32_t PtrAddFlags = 0;
+ // Each PtrAdd generated to implement the GEP inherits its nuw, nusw, inbounds
+ // flags.
if (const Instruction *I = dyn_cast<Instruction>(&U))
- Flags = MachineInstr::copyFlagsFromInstruction(*I);
+ PtrAddFlags = MachineInstr::copyFlagsFromInstruction(*I);
+
+ auto PtrAddFlagsWithConst = [&](int64_t Offset) {
+ // For nusw/inbounds GEP with an offset that is nonnegative when interpreted
+ // as signed, assume there is no unsigned overflow.
+ if (Offset >= 0 && (PtrAddFlags & MachineInstr::MIFlag::NoUSWrap))
+ return PtrAddFlags | MachineInstr::MIFlag::NoUWrap;
+ return PtrAddFlags;
+ };
----------------
ritter-x2a wrote:
The middle-end doesn't infer it in all cases, as far as I can tell: When I compile the following HIP code:
```
struct S {
int a;
int b[3];
int c;
};
__global__ void foo(S *p, int offset) {
p[offset].b[2] = 42;
}
```
with
```
clang -xhip --offload-arch=gfx1030 --driver-mode=g++ --offload-device-only -fglobal-isel -O3 -mllvm -print-before-all test.hip
```
I get this IR, without NUW, before the IRTranslator:
```
...
%0 = getelementptr inbounds %struct.S, ptr addrspace(1) %p.coerce.load, i64 %idxprom, i32 1, i64 0
%arrayidx23 = getelementptr inbounds i8, ptr addrspace(1) %0, i64 8
...
```
Without this check here, the `G_PTR_ADD`s in the generated MIR don't have NUW, with it the `G_PTR_ADD`s with a constant operand do.
I think part of the reason for that is that the last instance of instcombine runs before separate-const-offset-from-gep, so the [relevant transform in instcombine](https://github.com/llvm/llvm-project/blob/1862e3c56ce1eb3762b4ccd6e9e222f3022c9c7c/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp#L3409-L3416) only sees a single multi-offset GEP with one potentially negative offset, so it can't set NUW for the entire GEP.
https://github.com/llvm/llvm-project/pull/151708
More information about the llvm-commits
mailing list