The following testcase works on PPC with gcc-3.4, but fails with >=4.0. __extension__ typedef unsigned long long guint64; typedef int gint; typedef gint gboolean; typedef struct { guint64 rte; } mainwindow; mainwindow *mainw; static int bg_gen_to_start; gboolean weed_playback_gen_start (void) { bg_gen_to_start = -1; if (mainw->rte & (((guint64) 1) << bg_gen_to_start)) mainw->rte ^= (((guint64) 1) << bg_gen_to_start); } The error with mainline (only reproducible with atleast -O): test.c: In function 'weed_playback_gen_start': test.c:18: error: unrecognizable insn: (insn 37 36 39 2 (set (subreg:SI (reg:DI 119 [ D.1305 ]) 4) (ashift:SI (const_int 1 [0x1]) (const_int -1 [0xffffffffffffffff]))) -1 (nil) (nil)) test.c:18: internal compiler error: in extract_insn, at recog.c:2084
This works on the mainline as of today but failed with 4.2.0 20051219. Confirmed. Though I should note this is really weird as DOM is messing up in that version of GCC and we still have 1 << -1 which is not being folded.
Note that the code has undefined behaviour.
I think this is a bug in simplify_expand_binop (adding Richard Sandiford to the CC since he introduced that function). Currently when simplify_expand_binop is given two constants, it calls simplify_gen_binary. When the operation does not simplify, that will wind up returning RTL which may not satisfy the instruction predicates. I think it should call simplify_binary_operation instead. If that fails, it should call expand_binop as usual. I will attach a sample, untested, patch.
Created attachment 10590 [details] Sample untested patch
The patched compiler does build and does fix the testcase.
I can confirm it fixes it on my box as well.
Subject: Bug 25662 Author: dje Date: Sat Jan 7 22:23:27 2006 New Revision: 109456 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109456 Log: 2005-01-07 Ian Lance Taylor <ian@airs.com> David Edelsohn <edelsohn@gnu.org> PR rtl-optimization/25662 * optabs.c (simplify_expand_binop): Use simplify_binary_operation for constant operands instead of simplify_gen_binary. * simplify-rtx.c (simplify_gen_binary): Swap commutative operands after trying simplify_binary_operation Modified: trunk/gcc/ChangeLog trunk/gcc/optabs.c trunk/gcc/simplify-rtx.c
Subject: Bug 25662 Author: dje Date: Sun Jan 8 20:54:28 2006 New Revision: 109476 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109476 Log: 2006-01-08 Ian Lance Taylor <ian@airs.com> David Edelsohn <edelsohn@gnu.org> PR rtl-optimization/25662 * optabs.c (simplify_expand_binop): Use simplify_binary_operation for constant operands instead of simplify_gen_binary. Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/optabs.c
Subject: Bug 25662 Author: dje Date: Sun Jan 8 20:55:39 2006 New Revision: 109477 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109477 Log: 2006-01-08 Ian Lance Taylor <ian@airs.com> David Edelsohn <edelsohn@gnu.org> PR rtl-optimization/25662 * optabs.c (simplify_expand_binop): Use simplify_binary_operation for constant operands instead of simplify_gen_binary. Modified: branches/gcc-4_0-branch/gcc/ChangeLog branches/gcc-4_0-branch/gcc/optabs.c
Fix committed to all mainline, 4.1, 4.0.