[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #20 from Eric Gallager --- (In reply to Martin Sebor from comment #19) > That's a valid concern. Issuing a warning (either at the same time as or in > lieu of the folding) would be a way to detect and prevent these kinds of > problems. Exposing it to enough code (like in a whole distro rebuild) would > give us a pretty good idea about what the appropriate defaults ought to be. How exactly is this different from the warning discussed in bug 81453? It seems awfully similar to me...
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #1 from Marc Glisse --- > if (p >= a || p <= a + 3) I think you mean &&. I believe we could fold it to true or false as we wish: false because the preexisting pointer cannot point to a local object, true because you are only allowed to compare pointers into the same object.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #2 from Martin Sebor --- Yes, I meant &&. And yes, folding it either way is strictly valid in both C, where the result of the relational expression is undefined, and C++ where it's unspecified. But besides being inconsistent with the inequality (which is well-defined in both languages, except perhaps the dubious past-the-end case), knowing that the pointer cannot very well point into the local object, folding the relational expression to true would seem rather perverse. I wouldn't be surprised if it triggered (latent) bugs. Folding it to false, OTOH, seems safe,
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2019-07-23 Ever confirmed|0 |1 --- Comment #3 from Richard Biener --- Hmm, non-equality compares of different objects produce unspecified results, no? In those cases we usally are simply conservative... Otherwise we could simply fold all relations of non-aliasing pointers to false. Thus p >= a || p < a -> false. GIGO.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #4 from Martin Sebor --- The results of relational expressions (<, >, <=, and <=) involving pointers to unrelated objects are undefined and unspecified in C and C++, respectively. (See 6.5.8, p5 in C 11 and [expr.rel], p3 in C++ 17).
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #5 from rguenther at suse dot de --- On Tue, 23 Jul 2019, msebor at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 > > --- Comment #4 from Martin Sebor --- > The results of relational expressions (<, >, <=, and <=) involving pointers to > unrelated objects are undefined and unspecified in C and C++, respectively. > (See 6.5.8, p5 in C 11 and [expr.rel], p3 in C++ 17). Does "unspecified" allow p > q != !(p <= q)? I think so (it's not implementation defined). Still for GCC we need to find something sensible for QoI reasons. Eventually inserting a __builtin_trap () before a condition data dependent on such comparison is better than folding it to an essentially random constant (at least I don't see how we could easily get consistency here). So this might be something for path isolation, not so much for constant folding? Similar things could be done for uninitialized values participating in a controlling condition.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #6 from Marc Glisse --- When we compare p>=a where a is an array (char a[3];), we can assume that p points somewhere into the array and fold it to true (unless we decide that it is too risky, and that for instance since we allow pointers one past the end, we should also allow pointers one before the beginning). It is only in the rare case where we happen to know that p cannot point into the array that we might want to do something different (one possibility would be to fold the comparison to an undefined ssa_name), but that shouldn't prevent the 'true' optimization for valid code paths. Path isolation might arrive too late, after we have already folded to true.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #7 from rguenther at suse dot de --- On Wed, 24 Jul 2019, glisse at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 > > --- Comment #6 from Marc Glisse --- > When we compare p>=a where a is an array (char a[3];), we can assume that p > points somewhere into the array and fold it to true (unless we decide that it > is too risky, and that for instance since we allow pointers one past the end, > we should also allow pointers one before the beginning). That's generally possible for p >= &x, independent of whether x is an array. > It is only in the rare > case where we happen to know that p cannot point into the array that we might > want to do something different (one possibility would be to fold the > comparison > to an undefined ssa_name), but that shouldn't prevent the 'true' optimization > for valid code paths. Path isolation might arrive too late, after we have > already folded to true. Using an undef SSA name might trigger odd uninit warnings though, but yes. Note I've yet have to see a testcase that shows the optimization is useful for real code (the p >= &x I can imagine though), that is, optimize the case where we _know_ p and q do not point to the same object and p and q are compared with a non-equality compare. I'd say we should not fold and path-isolate the case instead (and consider moving that earlier if it's too late). Since such compares invoke undefined behavior I hope they do not come from STL template instantiation for example.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #8 from Martin Sebor --- (In reply to rguent...@suse.de from comment #5) > Does "unspecified" allow p > q != !(p <= q)? I think so (it's not > implementation defined). The exact C++ words that apply here are: (4.3) Otherwise [if two unequal pointers don't point into the same object], neither pointer is required to compare greater than the other. (it's not explicitly unspecified, but it sounds at least as loose). So the answer is yes. I agree with producing a sensible result for QoI (especially if there's no warning). A result that's consistent between [in]equality and relational expressions would qualify. I also agree that diagnosing all these unspecified (or undefined in C) cases would be helpful as they (at least in the straightforward instances) are most likely coding mistakes. I might look into it, though my first concern is about the instances that result from some earlier transformations and where warnings will be seen as false positives.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #9 from Marc Glisse --- (In reply to Martin Sebor from comment #8) > I also agree that diagnosing all these unspecified (or undefined in C) cases > would be helpful as they (at least in the straightforward instances) are > most likely coding mistakes. Note that there is already a sanitizer for that. Of course it isn't the same as a warning.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 Eric Gallager changed: What|Removed |Added CC||egallager at gcc dot gnu.org See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=81453 --- Comment #10 from Eric Gallager --- (In reply to Martin Sebor from comment #8) > (In reply to rguent...@suse.de from comment #5) > > Does "unspecified" allow p > q != !(p <= q)? I think so (it's not > > implementation defined). > > The exact C++ words that apply here are: > > (4.3) Otherwise [if two unequal pointers don't point into the same object], > neither pointer is required to compare greater than the other. > > (it's not explicitly unspecified, but it sounds at least as loose). So the > answer is yes. > > I agree with producing a sensible result for QoI (especially if there's no > warning). A result that's consistent between [in]equality and relational > expressions would qualify. > > I also agree that diagnosing all these unspecified (or undefined in C) cases > would be helpful as they (at least in the straightforward instances) are > most likely coding mistakes. I might look into it, though my first concern > is about the instances that result from some earlier transformations and > where warnings will be seen as false positives. Now that you're getting into the diagnostics aspect of this I'd just like to point out that this could be tied in with fixing bug 81453 at the same time and the new warnings could be grouped under the -Wordered-pointer-comparison flag proposed there
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 Florian Weimer changed: What|Removed |Added CC||fw at gcc dot gnu.org --- Comment #11 from Florian Weimer --- (In reply to Richard Biener from comment #3) > Hmm, non-equality compares of different objects produce unspecified results, > no? GCC on ELF provides defined address ordering for separate objects via linker ordering and section attributes. I think part of these extensions is that it is possible to check at run time whether an object falls into a specific section, and where. Support for this must be preserved in some fashion.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #12 from Marc Glisse --- (In reply to Florian Weimer from comment #11) > GCC on ELF provides defined address ordering for separate objects via linker > ordering and section attributes. I think part of these extensions is that > it is possible to check at run time whether an object falls into a specific > section, and where. Support for this must be preserved in some fashion. How about casting to uintptr_t before comparing? It isn't really formalized, but I think that's the extension gcc provides to safely do such comparisons.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #13 from Florian Weimer --- (In reply to Marc Glisse from comment #12) > (In reply to Florian Weimer from comment #11) > > GCC on ELF provides defined address ordering for separate objects via linker > > ordering and section attributes. I think part of these extensions is that > > it is possible to check at run time whether an object falls into a specific > > section, and where. Support for this must be preserved in some fashion. > > How about casting to uintptr_t before comparing? It isn't really formalized, > but I think that's the extension gcc provides to safely do such comparisons. I don't see why I cast should magically fix this issue, when it it does not help with broadly similar matters related to aliasing. A documented GCC extensions would help, of course.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #14 from Marc Glisse --- (In reply to Florian Weimer from comment #13) > I don't see why I cast should magically fix this issue, In libstdc++, std::less does such a cast, there were discussions about it at that time.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #15 from Martin Sebor --- I agree that comparison of the intptr_t values would be preferable over extending the pointer inequality semantics. It's the intended mechanism for this sort query. It makes code that relies on the ordering of unrelated objects easy to distinguish from accidental pointer misuses, which in turn makes it possible to both detect bugs and emit better object code.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #16 from joseph at codesourcery dot com --- I think the most likely case for code using such comparisons is not a mistake, but code doing something like memmove - code that checks whether two arrays overlap, and which one comes first if they do overlap, in order to decide how to carry out some operation on those arrays that may modify them in-place.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #17 from Martin Sebor --- Just to be clear: my suggestion to fold the relational expressions is only for incoming pointers with addresses of local variables that GCC already assumes cannot be synthesized (I assume it does that on the basis of what the provenance proposals refer to as address nondeterminism). I am not suggesting to fold arbitrary relational expressions in general.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #18 from joseph at codesourcery dot com --- I don't expect people to do such comparisons with addresses of local variables directly. It is plausible that they have a memmove-like function, and once it gets inlined the compiler can see that, at a particular call site, it's doing such comparisons involving addresses of local variables. The question then is whether this might result in problems if e.g. the comparisons say two arrays are both before and after each other and the memmove-like function isn't prepared for that. And, then, whether we say that's OK and such a function needs to cast to uintptr_t as the way to make something that's valid in C-with-ABI-boundaries into something that works in GNU C in the presence of (possibly LTO) inlining.
[Bug tree-optimization/91227] pointer relational expression not folded but equivalent inequality is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91227 --- Comment #19 from Martin Sebor --- That's a valid concern. Issuing a warning (either at the same time as or in lieu of the folding) would be a way to detect and prevent these kinds of problems. Exposing it to enough code (like in a whole distro rebuild) would give us a pretty good idea about what the appropriate defaults ought to be.