From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100034 invoked by alias); 22 May 2015 08:52:13 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 99999 invoked by uid 48); 22 May 2015 08:52:09 -0000 From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/65752] Too strong optimizations int -> pointer casts Date: Fri, 22 May 2015 08:52:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 4.9.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-05/txt/msg01882.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65752 Richard Biener changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at gcc dot gnu.org --- Comment #32 from Richard Biener --- (In reply to Chung-Kil Hur from comment #29) > Dear Richard, > > This time, I think I constructed a real bug. > Please have a look and correct me if I am wrong. > > ===================== > #include > > int main() { > int x = 0; > uintptr_t xp = (uintptr_t) &x; > uintptr_t i; > > for (i = 0; i < xp; i++) { } > > *(int*)xp = 15; > > printf("%d\n", x); > } > ===================== > > This program prints "15" and I do not think this raises UB. > > Now I add an if-statement to the program. > > ===================== > #include > > int main() { > int x = 0; > uintptr_t xp = (uintptr_t) &x; > uintptr_t i; > > for (i = 0; i < xp; i++) { } > > /*** begin ***/ > if (xp != i) { > printf("hello\n"); > xp = i; > } > /*** end ***/ > > *(int*)xp = 15; > > printf("%d\n", x); > } > ===================== > > This program just prints "0". > > Since "hello" is not printed, the if-statement is not executed. > However, it prints a different result than before, which I think is a bug. It indeed is a more unfortunate case but you are still breaking the dependency chain in the if (xp != i) code by assigning i to xp. The code is never executed (which is why this is unfortunate) and I am less than 100% sure it still invokes undefined behavior. The unfortunate thing is that the equivalence you build on the 'else' path (xp == i) is used by the compiler to replace xp by i on the *(int*)xp = 15 line getting us into the very same situation as in all other cases. That is, we have if (xp != i) ... # xp = PHI *(int *)xp = 15; because of the conditional and in this case our phiopt pass optimizes that to # xp = PHI instead of the equally valid # xp = PHI other passes (dom) may end up doing a similar thing (at least for GCC 5 and the particular testcase we are lucky here though), but for GCC 5 -fdisable-tree-phiopt1 -fdisable-tree-phiopt2 avoids the issue. Generally there is no good way to determine which choice is better. What the PTA code does is sensible btw. For # xp_20 = PHI <0(2), xp_7(7)> xp_7 = xp_20 + 1; if (xp_6 > xp_7) goto ; else goto ; : goto ; the PTA constraints are xp_6 = &x xp_20 = &NULL xp_20 = xp_7 xp_7 = xp_20 xp_7 = &NONLOCAL which means PTA considers that all pointers coming from integer constants point to global memory only (that's to support fixed address objects). That helps to avoid false aliasing to stack objects and avoids the need to make all locals escaped when you have code passing an integer to a function (that integer, converted to a pointer _could_ point to a stack slot in the caller, no?!). So 'i' is considered to eventually point to arbitrary global memory. But _not_ to arbitrary address-taken locals.