[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Jeffrey A. Law changed: What|Removed |Added Status|NEW |RESOLVED CC||law at redhat dot com See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=81601 Resolution|--- |FIXED --- Comment #19 from Jeffrey A. Law --- So the core issue here, using an if, conditional moves and the like to do single bit field extraction/testing is resolved. There is still an issue of canonicalizing the two representations which in turn opens up the possibility of finding more common subexpressions when both forms might be used. That is actually being tracked via pr81601.
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #18 from Bill Schmidt --- I agree with Matthew.
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Matthew Fortune changed: What|Removed |Added CC||matthew.fortune at imgtec dot com --- Comment #17 from Matthew Fortune --- (In reply to Bill Schmidt from comment #15) > ;; Function andrew (andrew, funcdef_no=2, decl_uid=2361, cgraph_uid=2, > symbol_order=2) > > andrew (struct s * p) > { > unsigned int _4; > unsigned int _5; > unsigned int _6; > > : > _4 = BIT_FIELD_REF <*p_3(D), 32, 0>; > _5 = _4 & 1; > _6 = _5; > return _6; > > } MIPS sees this same spurious failure. The issue (on a GCC 6 branch) is that the optimization has successfully happened it just looks like the check is wrong in the testcase. The presence of a logical and is not harmful as it is a legitimate way to truncate: (from match.pd) /* A truncation to an unsigned type (a zero-extension) should be canonicalized as bitwise and of a mask. */ This simplification kicks in for MIPS and presumably powerpc but does not (I don't know why) for x86_64. There is no 'goto' demonstrating that a single bit extract does not use an IF. I therefore propose we just update the check to verify there is no 'goto'. Matthew
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #16 from Richard Biener --- (In reply to Steven Bosscher from comment #6) > The tree dump for the original test case now looks like this for me: > > ;; Function foo (foo) > > foo (p) > { > : > return (unsigned int) ((BIT_FIELD_REF <*p, 8, 0> & 1) != 0); > > } > > > > ;; Function bar (bar) > > bar (p) > { > : > return (unsigned int) p->bit; > > } > > > > The resulting assembler output is the same, but I imagine VRP should be able > to fold away the "& 1" test. I don't know if the BIT_FIELD_REF itself > should be optimized away, but I guess so. Consider the following test case: > > struct s > { > unsigned int bit:1; > }; > > unsigned int > foo (struct s *p) > { > if (p->bit) > return (unsigned int) (p->bit); > else > return 0; > } > > > This gets "optimized" at the tree level to this ugly code: > ;; Function foo (foo) > > foo (p) > { > unsigned int D.1979; > > : > if ((BIT_FIELD_REF <*p, 8, 0> & 1) != 0) goto ; else goto ; > > :; > D.1979 = 0; > goto (); > > :; > D.1979 = (unsigned int) p->bit; > > :; > return D.1979; > > } > > In summary, I don't think we can close this bug just yet. I don't think VRP can optimize anything here as the BIT_FIELD_REF created by optimize_bitfield_compare accesses struct s tail-padding. IMHO this is still very premature optimization done by fold.
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #15 from Bill Schmidt --- My preference is to see the test properly resolved. :) I don't think you should just XFAIL the powerpc64le case without understanding why it fails, as that tends to leave the XFAIL in place forever. Here is pr15826.c.211t.optimized on powerpc64le with -O2. Hopefully that will help you see what's going on. Please let me know if there is other data I can gather that will be useful. Thanks! Bill ;; Function foo (foo, funcdef_no=0, decl_uid=2355, cgraph_uid=0, symbol_order=0) foo (struct s * p) { unsigned int _4; unsigned int _5; unsigned int _7; : _4 = BIT_FIELD_REF <*p_3(D), 32, 0>; _5 = _4 & 1; _7 = _5; return _7; } ;; Function bar (bar, funcdef_no=1, decl_uid=2358, cgraph_uid=1, symbol_order=1) bar (struct s * p) { _3; unsigned int _4; : _3 = p_2(D)->bit; _4 = (unsigned int) _3; return _4; } ;; Function andrew (andrew, funcdef_no=2, decl_uid=2361, cgraph_uid=2, symbol_order=2) andrew (struct s * p) { unsigned int _4; unsigned int _5; unsigned int _6; : _4 = BIT_FIELD_REF <*p_3(D), 32, 0>; _5 = _4 & 1; _6 = _5; return _6; }
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #14 from Martin Sebor --- (In reply to Andrew Pinski from comment #12) Thank your for catching it. I did actually read all the comments. The trouble is that there are several test cases here and I missed the one in the second half of comment #6 (the first half of the comment doesn't seem to apply anymore, at least not on x86_64). (In reply to Bill Seurer from comment #13) You're right, the test fails on powerpc64le (though as far as I can see not on any other target with reported test results). It seems like a useful test despite the above so rather than backing it out entirely I could disable it for powerpc64le until it's analyzed. Bill (Seurer or Schmidt), does either of you have a preference for how to handle the failure?
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Bill Seurer changed: What|Removed |Added CC||seurer at linux dot vnet.ibm.com --- Comment #13 from Bill Seurer --- The test case also fails on powerpc64 LE (but seem to work on BE) Executing on host: /home/seurer/gcc/build/gcc-test/gcc/xgcc -B/home/seurer/gcc/build/gcc-test/gcc/ /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/tree-ssa/pr15826.c -fno-diagnostics-show-caret -fdiagnostics-color=never -O2 -fdump-tree-optimized -S -o pr15826.s(timeout = 300) spawn /home/seurer/gcc/build/gcc-test/gcc/xgcc -B/home/seurer/gcc/build/gcc-test/gcc/ /home/seurer/gcc/gcc-test/gcc/testsuite/gcc.dg/tree-ssa/pr15826.c -fno-diagnostics-show-caret -fdiagnostics-color=never -O2 -fdump-tree-optimized -S -o pr15826.s PASS: gcc.dg/tree-ssa/pr15826.c (test for excess errors) FAIL: gcc.dg/tree-ssa/pr15826.c scan-tree-dump-times optimized " & | goto " 0
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Andrew Pinski changed: What|Removed |Added Status|RESOLVED|NEW Resolution|FIXED |--- --- Comment #12 from Andrew Pinski --- You did not read my comment #8. Please read it again and try it again. Your testcase does not cover the testcase mentioned in comment #6.
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Martin Sebor changed: What|Removed |Added Status|NEW |RESOLVED CC||msebor at gcc dot gnu.org Known to work||5.1.0, 6.0 Resolution|--- |FIXED --- Comment #11 from Martin Sebor --- It looks to me like the missing optimization now takes place, and has since 5.1. In both foo() and andrew() the bit test is optimized away during cddce2 resulting in the following. The BIT_FIELD_REF is still there, but I assume that's fine. I'll go ahead, add the test case to the test suite and resolve this as fixed. Please reopen if I missed something. foo (struct s * p) { unsigned char _4; _Bool _6; unsigned int _7; : _4 = BIT_FIELD_REF <*p_3(D), 8, 0>; _6 = (_Bool) _4; _7 = (unsigned int) _6; return _7; }
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #10 from Martin Sebor --- Author: msebor Date: Fri Feb 26 23:24:29 2016 New Revision: 233771 URL: https://gcc.gnu.org/viewcvs?rev=233771&root=gcc&view=rev Log: PR tree-optimization/15826 - don't use "if" to extract a single bit bit-field 2016-02-26 Martin Sebor PR tree-optimization/15826 * gcc.dg/tree-ssa/pr15826.c: New test. Added: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr15826.c Modified: trunk/gcc/testsuite/ChangeLog
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 --- Comment #9 from Richard Biener --- Which boils down to the premature fold-const.c:optimize_bit_field_compare which creates this BIT_FIELD_REF (fold_truth_andor_1 does similar stupid stuff).
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Bug 15826 depends on bug 15459, which changed state. Bug 15459 Summary: [meta-bug] there should be a tree combiner like the rtl one https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15459 What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826 Andrew Pinski changed: What|Removed |Added CC|gcc-bugs at gcc dot gnu.org | --- Comment #8 from Andrew Pinski 2012-01-24 00:03:45 UTC --- (In reply to comment #6) Only comment #6 remains to be fixed. FRE does not recognize p->bit as "BIT_FIELD_REF <*p, 8, 0> & 1".
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
--- Comment #7 from rguenth at gcc dot gnu dot org 2008-04-30 19:21 --- On the trunk I have after phiopt1: ;; Function andrew (andrew) Removing basic block 3 Merging blocks 2 and 4 andrew (struct s * p) { _Bool D.1212; int i; unsigned int D.1183; D.1182; : D.1182_3 = p_2(D)->bit; (void) 0; D.1212_9 = D.1182_3 != 0; i_10 = (int) D.1212_9; D.1183_6 = (unsigned int) i_10; return D.1183_6; } ;; Function foo (foo) Removing basic block 3 Merging blocks 2 and 4 foo (struct s * p) { _Bool D.1199; unsigned int D.1177; D.1176; : D.1176_3 = p_2(D)->bit; (void) 0; D.1199_8 = D.1176_3 != 0; D.1177_9 = (unsigned int) D.1199_8; return D.1177_9; } which the next forwprop pass optimizes to foo (struct s * p) { unsigned int D.1177; D.1176; : D.1176_3 = p_2(D)->bit; D.1177_9 = D.1176_3 != 0; return D.1177_9; } andrew (struct s * p) { unsigned int D.1183; D.1182; : D.1182_3 = p_2(D)->bit; D.1183_6 = D.1182_3 != 0; return D.1183_6; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
--- Comment #6 from steven at gcc dot gnu dot org 2007-04-05 22:01 --- The tree dump for the original test case now looks like this for me: ;; Function foo (foo) foo (p) { : return (unsigned int) ((BIT_FIELD_REF <*p, 8, 0> & 1) != 0); } ;; Function bar (bar) bar (p) { : return (unsigned int) p->bit; } The resulting assembler output is the same, but I imagine VRP should be able to fold away the "& 1" test. I don't know if the BIT_FIELD_REF itself should be optimized away, but I guess so. Consider the following test case: struct s { unsigned int bit:1; }; unsigned int foo (struct s *p) { if (p->bit) return (unsigned int) (p->bit); else return 0; } This gets "optimized" at the tree level to this ugly code: ;; Function foo (foo) foo (p) { unsigned int D.1979; : if ((BIT_FIELD_REF <*p, 8, 0> & 1) != 0) goto ; else goto ; :; D.1979 = 0; goto (); :; D.1979 = (unsigned int) p->bit; :; return D.1979; } In summary, I don't think we can close this bug just yet. -- steven at gcc dot gnu dot org changed: What|Removed |Added Last reconfirmed|2005-12-10 04:15:46 |2007-04-05 22:01:25 date|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
--- Comment #5 from pinskia at gcc dot gnu dot org 2006-03-02 14:24 --- This is interesting, we now get BIT_FIELD_REF. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826
[Bug tree-optimization/15826] don't use "if" to extract a single bit bit-field.
-- Bug 15826 depends on bug 15618, which changed state. Bug 15618 Summary: Missed bool optimization http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15618 What|Old Value |New Value Status|NEW |ASSIGNED Status|ASSIGNED|RESOLVED Resolution||FIXED http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15826