[PATCH] D22793: IR: Introduce inbounds attribute on getelementptr indices.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 7 11:51:12 PDT 2016


pcc added a comment.

Apologies for the delayed response, I just returned from a long vacation.


================
Comment at: include/llvm/IR/Operator.h:382
@@ -381,1 +381,3 @@
   }
+  /// Returns the offset of the index with an inrange attachment, or None if
+  /// none.
----------------
pete wrote:
> Sorry to come late to this one...
> 
> My read on this implies that inrange on the start of a GEP would be equivalent to inbounds today.  Is that the case?
> 
> Assuming it is, the inrange is strictly a more accurate version of inbounds, and we should only have inrange.  Put another way, keep the name inbounds, but allow it to be applied to any single type in the GEP.
> 
> So that would make all of these equivalent in terms of AA, and all of these alias each other:
>   %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2
>   %arrayidx = getelementptr %struct.ST, %struct.ST* %s, inbounds i64 1, i32 2
>   %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, inbounds i32 2
> 
> But these won't alias because the inbounds applies to an index with a different value:
>   %arrayidx = getelementptr %struct.ST, %struct.ST* %s, inbounds i64 0, i32 2
>   %arrayidx = getelementptr %struct.ST, %struct.ST* %s, inbounds i64 1, i32 2
> 
> And these will alias because one has inbounds and the other doesn't:
>   %arrayidx = getelementptr %struct.ST, %struct.ST* %s, i64 0, i32 2
>   %arrayidx = getelementptr %struct.ST, %struct.ST* %s, inbounds i64 1, i32 2
> My read on this implies that inrange on the start of a GEP would be equivalent to inbounds today. Is that the case?

No. The inbounds keyword is a bounds restriction with regard to the allocated object, while inrange on the start of the GEP is a bounds restriction with regard to the GEP element type (or subelement type). The inrange restriction also applies to any pointers derived from the inrange GEP, while this isn't the case for inbounds. So, for example if you have an allocated object of type `[2 x %struct.ST]` and a pointer `%s` referring to its first element, and the instructions
```
%i1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 0
%i2 = getelementptr %struct.ST, %struct.ST* %s, inrange i64 0
```

the instruction
```
%i1a = getelementptr %struct.ST, %struct.ST* %i1, i64 1
```
would yield a pointer to the second element of the allocated object but the instruction
```
%i2a = getelementptr %struct.ST, %struct.ST* %i2, i64 1
```
would yield an undefined value.


https://reviews.llvm.org/D22793





More information about the llvm-commits mailing list