[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #12 from Sergei Trofimovich --- I confirm the change fixed `perf` startup for me. Thank you!
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #11 from CVS Commits --- The master branch has been updated by Andrew Macleod : https://gcc.gnu.org/g:dc48d1d1d4458773f89f21b2f019f66ddf88f2e5 commit r14-3296-gdc48d1d1d4458773f89f21b2f019f66ddf88f2e5 Author: Andrew MacLeod Date: Thu Aug 17 11:13:14 2023 -0400 Fix range-ops operator_addr. Lack of symbolic information prevents op1_range from beig able to draw the same conclusions as fold_range can. PR tree-optimization/111009 gcc/ * range-op.cc (operator_addr_expr::op1_range): Be more restrictive. gcc/testsuite/ * gcc.dg/pr111009.c: New.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #10 from Andrew Macleod --- > At the hazard of stating the obvious: it's a wrong-code when you execute it > (not a gcc ICE). > doh. of course. test is in progress. Richi was correct. Although the code in range-ops for fold_range is correct, op1_range cannot make the same assumptions that fold_range does because it has no concept of the symbolic values on the RHS. I am making op1_range more restrictive.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #9 from Sergei Trofimovich --- Created attachment 55744 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55744=edit bug.S At the hazard of stating the obvious: it's a wrong-code when you execute it (not a gcc ICE). Should fail on vanilla x86_64-linux-gnu. Tested on today's r14-3254-g9ade70bb86c874 as: $ gcc -Bgcc bug.c.c -fno-strict-overflow -O3 -o bug && ./bug Segmentation fault (core dumped) I also uploaded bug.S as an output of $ gcc -Bgcc bug.c.c -fno-strict-overflow -O3 -S -fverbose-asm -o bug.S if it helps you to find why your output is different.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #8 from Andrew Macleod --- Do I need some special target or something? on trunk just "-fno-strict-overflow -O3" doesnt fail for me on x86_64-pc-linux-gnu... ./cc1 -fno-strict-overflow -O3 009.c -quiet
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #7 from Sergei Trofimovich --- commit bd400db6d3ec167142ace352db00f84d382e33a8 (HEAD) Date: Fri Oct 15 12:06:27 2021 -0400 Add --param=vrp1-mode and --param=vrp2-mode. (the first commit that adds the option) generates SIGSEGVs all the same: $ gcc/xgcc -Bgcc ~/dev/bugs/gcc-14-perf-wrong-code-PR111009/bug.c.c -fno-strict-overflow -O3 -o bug --param=vrp2-mode=ranger && ./bug Segmentation fault (core dumped) Not much to bisect.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #6 from Sam James --- Can you bisect further back with -param=vrp2-mode=ranger, to force ranger before it was the default?
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #5 from Sergei Trofimovich --- For what it's worth bisect pointed at r12-4871-g502ffb1f389011 $ git bisect good 502ffb1f389011b28ee51815242c7397790802d5 is the first bad commit commit 502ffb1f389011b28ee51815242c7397790802d5 Date: Tue Nov 2 21:26:44 2021 -0400 Switch vrp2 to ranger.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #4 from Andrew Macleod --- (In reply to Richard Biener from comment #3) > bool > operator_addr_expr::fold_range (irange , tree type, > const irange , > const irange , > relation_trio) const > { > if (empty_range_varying (r, type, lh, rh)) > return true; > > // Return a non-null pointer of the LHS type (passed in op2). > if (lh.zero_p ()) > r = range_zero (type); > > not sure how this is called, but we can only derive this if the offset > is zero as well, definitely if targetm.addr_space.zero_address_valid, > but I think this is true in general. > > else if (!contains_zero_p (lh)) > r = range_nonzero (type); > > and this is only true for TYPE_OVERFLOW_UNDEFINED (type), with > -fwrapv-pointer we could wrap to zero. > > That is, it's _not_ GIMPLE undefined behavior to compute &0->bar. > It looks like without -fwrapv-pointer we elide the if (!a) check, > dereferencing it when dso && dso != curr. I suppose that looks reasonable > with a = >maj, when dso != 0 then a != 0 unless ->maj wraps. Range-ops won't see anything like >maj.. it sees rangers and nothing else. it just gets the result of that expression determined by someone else. . so if it see [0,0] for the range, that means >maj has been determined to be 0. When folding, addressof has some funky mechanics, and it symbolically processes the trees in gimple-range-fold.cc in fold_using_range::range_of_address I think it takes care of all the funky things you mention. I also notice in the earlier comment where we set _13 to 0... the code you quoted where _13 was recomputed by ranger. it ends with GORI TRUE : (797) recomputation (_13) [irange] _Bool [1, 1] The result was [1,1] as far as ranger was concerned o the edge from 3->16 so that prop0bably isn't how gimple fold determined it was zero. Is there still an issue here?
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 --- Comment #3 from Richard Biener --- bool operator_addr_expr::fold_range (irange , tree type, const irange , const irange , relation_trio) const { if (empty_range_varying (r, type, lh, rh)) return true; // Return a non-null pointer of the LHS type (passed in op2). if (lh.zero_p ()) r = range_zero (type); not sure how this is called, but we can only derive this if the offset is zero as well, definitely if targetm.addr_space.zero_address_valid, but I think this is true in general. else if (!contains_zero_p (lh)) r = range_nonzero (type); and this is only true for TYPE_OVERFLOW_UNDEFINED (type), with -fwrapv-pointer we could wrap to zero. That is, it's _not_ GIMPLE undefined behavior to compute &0->bar. It looks like without -fwrapv-pointer we elide the if (!a) check, dereferencing it when dso && dso != curr. I suppose that looks reasonable with a = >maj, when dso != 0 then a != 0 unless ->maj wraps.
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |NEW CC||amacleod at redhat dot com, ||rguenth at gcc dot gnu.org Priority|P3 |P2 Target Milestone|--- |12.4 Last reconfirmed||2023-08-14 Ever confirmed|0 |1 --- Comment #2 from Richard Biener --- There's nothing really wrong with lifting the >maj computation, on GIMPLE >maj is just address arithmetic. Interestingly we unswitch the loop but only with -fwrapv-pointer. OK, so the bug looks like we have if (>maj != 0) for (;;) { if (!dso) return 1; if (dso == curr) return 1; ... } and the if (!dso) test is optimized away since >maj != 0. That's done by DOM3 here: Optimizing statement _21 = dso_8(D) == _11; LKUP STMT _21 = dso_8(D) eq_expr _11 2>>> STMT _21 = dso_8(D) eq_expr _11 Optimizing statement _22 = _21 | _13; Replaced '_13' with constant '0' Applying pattern match.pd:201, gimple-match-10.cc:6318 gimple_simplified to _22 = _21; Folded to: _22 = _21; I don't see where _13 = 0 is entered, this is possibly ranger related: _13 : CACHE: BB 9 DOM query for _13, found [irange] _Bool VARYING at BB3 797 GORI recomputation attempt on edge 3->16 for _13 = dso_8(D) == 0B; 798 GORIoutgoing_edge for dso_8(D) on edge 3->16 799 GORI compute op 1 (a_9) at if (a_9 == 0B) GORILHS =[irange] _Bool [1, 1] GORIComputes a_9 = [irange] int * [0, 0] intersect Known range : [irange] int * VARYING GORI TRUE : (799) produces (a_9) [irange] int * [0, 0] 800 GORI compute op 1 (dso_8(D)) at a_9 = _8(D)->maj; GORILHS =[irange] int * [0, 0] GORIComputes dso_8(D) = [irange] struct dso * [0, 0] intersect Known range : [irange] struct dso * VARYING GORI TRUE : (800) produces (dso_8(D)) [irange] struct dso * [0, 0] GORITRUE : (798) outgoing_edge (dso_8(D)) [irange] struct dso * [0, 0] GORI TRUE : (797) recomputation (_13) [irange] _Bool [1, 1] I don't think we can do this. Andrew?
[Bug middle-end/111009] [12/13/14 regression] -fno-strict-overflow erroneously elides null pointer checks and causes SIGSEGV on perf from linux-6.4.10
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009 Alexander Monakov changed: What|Removed |Added CC||amonakov at gcc dot gnu.org --- Comment #1 from Alexander Monakov --- Triggered by GIMPLE loop invariant motion lifting a_9 = _8(D)->maj; across a (dso != NULL) test.