pointer comparison in GIMPLE

Richard Biener richard.guenther@gmail.com
Thu Dec 11 11:38:43 GMT 2025


On Thu, Dec 11, 2025 at 5:12 AM Krister Walfridsson
<krister.walfridsson@gmail.com> wrote:
>
> On Wed, 10 Dec 2025, Richard Biener wrote:
>
> >> The problem is that in GIMPLE, a pointer does not need to be in bounds. The caller could call the function with a value of i such that p + i happens to be equal to &a. So, as I understand it, the GIMPLE semantics do not allow the pass to conclude that p + i == &a is false, unless p + i is dereferenced (because dereferencing a through p + i would be UB due to provenance).
> >
> > GIMPLE adopts most of the C pointer restrictions here thus we can (and do) conclude that pointers stay within an object when advanced.  This is used by the PTA pass which results are used when we optimize your example.  You have to divert to integer arithmetic to circumvent this and the PTA pass, while tracking provenance through integers as well, does the right thing with this.
>
> Great, that is much better for smtgcc than the semantics I have currently
> implemented!
>
> But it is not completely clear to me what "most of the C pointer
> restrictions" implies. Is the following a correct interpretation?
>
> 1. A pointer must contain a value that points into (or one past) an object
> corresponding to its provenance (where a pointer may have multiple
> provenances). Otherwise it invokes undefined behavior.

Hmm.  I think it's only UB when you'd "use" that pointer.  That is, PTA would
compute the points-to set to 'nothing'.  The immediate consequences are such
pointer isn't equal to any other pointer and accesses through it alias
with nothing,
stores would be DSEd.  But at the point a SSA var is assigned such a pointer
we couldn't place a trap() (?)

> 2. The provenance used for the result of POINTER_PLUS is the union of the
> provenances for the two arguments.

For POINTER_PLUS it's the provenance of the first argument.

For PLUS_EXPR it is the union of both arguments.  For POINTER_DIFF_EXPR
the result has no provenance.

> 3. The POINTER_PLUS operation is UB if the calculation overflows and
> TYPE_OVERFLOW_WRAPS(ptr_type) is false.

Yes.

> 4. The rules are the same for the calculations done in MEM_REF and
> TARGET_MEM_REF as for POINTER_PLUS.

Yes.

> Question: For the TARGET_MEM_REF calculation:
>    BASE + STEP * INDEX + INDEX2 + OFFSET
> Is it treated as one POINTER_PLUS, i.e.
>    BASE + (STEP * INDEX + INDEX2 + OFFSET)
> or as two (i.e. do we care about overflow and OOB between the two index
> calculations)?

I'd say it counts as one pointer + offset calculation with all the offset
calculation being done in wrapping operations.

>
>
> FWIW, the vectorizer and ivopts do introduce pointers that are outside the
> object (which is why I allowed it in my current semantics)...

But only "slightly" ... that is, we consider it having the objects provenance
still given the vectorizer/ivopts will ensure actual accesses do not access
another object [in a way a program can observe].

>     /Krister


More information about the Gcc mailing list