The following two functions should produce the same assembly int f(int a) { a|=1; a^=1; return a; } int f1(int a) { return a&~1; }
Another example where we don't get the optimization and f1 is still one instruction (on 32bit PPC): int f(int a,int b) { a|=b; a^=b; return a; } int f1(int a,int b) { return a&=~b; }
I had forgot to mention, I found this when Nathan was asking about a~=b (aka a&=~b) and Segher sugessted a^=b;a|=b; and then we (Segher and I) both noticed that gcc was not doing the optimization.
If we changed the function in comment #0 like so: int f(int a) { a=(a|1)^1; return a; } Fold should do this simplification. And likewise for comment #1 (which is just general case): int f(int a,int b) { a=(a|b) ^ b; return a; }
I have a fix which I will be testing over night.
Created attachment 9203 [details] Patch which I am testing ChangeLog: * fold-const.c (fold_binary): Transform "(X | Y) ^ X" to "Y & ~ X".
Patch posted here: <http://gcc.gnu.org/ml/gcc-patches/2005-07/msg00258.html>.
Subject: Bug 19055 CVSROOT: /cvs/gcc Module name: gcc Changes by: pinskia@gcc.gnu.org 2005-07-21 19:33:50 Modified files: gcc : ChangeLog fold-const.c gcc/testsuite : ChangeLog Log message: 2005-07-21 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/19055 * gcc.dg/tree-ssa/pr19055.c: New test. * gcc.dg/tree-ssa/pr19055-2.c: New test. 2005-07-21 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/19055 * fold-const.c (fold_binary): Transform "(X | Y) ^ X" to "Y & ~ X". Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9501&r2=2.9502 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.606&r2=1.607 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5798&r2=1.5799
Fixed.