On Thu, Dec 11, 2025 at 5:12 AM Krister Walfridsson <[email protected]> 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
