http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47299
--- Comment #1 from rguenther at suse dot de <rguenther at suse dot de> 2011-01-14 21:49:32 UTC --- On Fri, 14 Jan 2011, uweigand at gcc dot gnu.org wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47299 > > Summary: Widening multiply optimization generates bad code > Product: gcc > Version: 4.5.0 > Status: UNCONFIRMED > Keywords: wrong-code > Severity: normal > Priority: P3 > Component: rtl-optimization > AssignedTo: unassig...@gcc.gnu.org > ReportedBy: uweig...@gcc.gnu.org > CC: ber...@codesourcery.com, rguent...@suse.de > > > Building the following test case with current mainline on i386: > > unsigned short test (unsigned char val) __attribute__ ((noinline)); > > unsigned short > test (unsigned char val) > { > return val * 255; > } > > int > main(int argc, char**argv) > { > printf ("test(val=40) = %x\n", test(0x40)); > return 0; > } > > We get the following (correct) output with -O0: > test(val=40) = 3fc0 > > and the following incorrect output with -O2: > test(val=40) = ffc0 > > The problem appears to be related to this piece of code in expand_expr_real2, > case WIDEN_MULT_EXPR: > > expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, > EXPAND_NORMAL); > temp = expand_widening_mult (mode, op0, op1, target, > unsignedp, this_optab); > > expand_operands will expand the constant 255 into QImode and return a > (const_int -1) for op1. Passing this constant into expand_widening_mult then > apparently generates a simple negation operation in HImode instead (via > expand_const_mult) ... > > It seems this code came in here: > http://gcc.gnu.org/ml/gcc-patches/2010-04/msg01327.html > Any suggestions how this ought to be handled? I think we need to pass the narrow mode explicitly. Richard.