2011-01-18 Ulrich Weigand LP: #685352 Backport from mainline: 2011-01-18 Jakub Jelinek gcc/ PR rtl-optimization/47299 * expr.c (expand_expr_real_2) : Don't use subtarget. Use normal multiplication if both operands are constants. * expmed.c (expand_widening_mult): Don't try to optimize constant multiplication if op0 has VOIDmode. Convert op1 constant to mode before using it. gcc/testsuite/ PR rtl-optimization/47299 * gcc.c-torture/execute/pr47299.c: New test. === modified file 'gcc/expmed.c' Index: gcc-4_5-branch/gcc/expmed.c =================================================================== --- gcc-4_5-branch.orig/gcc/expmed.c +++ gcc-4_5-branch/gcc/expmed.c @@ -3355,12 +3355,17 @@ expand_widening_mult (enum machine_mode int unsignedp, optab this_optab) { bool speed = optimize_insn_for_speed_p (); + rtx cop1; if (CONST_INT_P (op1) - && (INTVAL (op1) >= 0 + && GET_MODE (op0) != VOIDmode + && (cop1 = convert_modes (mode, GET_MODE (op0), op1, + this_optab == umul_widen_optab)) + && CONST_INT_P (cop1) + && (INTVAL (cop1) >= 0 || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)) { - HOST_WIDE_INT coeff = INTVAL (op1); + HOST_WIDE_INT coeff = INTVAL (cop1); int max_cost; enum mult_variant variant; struct algorithm algorithm; Index: gcc-4_5-branch/gcc/expr.c =================================================================== --- gcc-4_5-branch.orig/gcc/expr.c +++ gcc-4_5-branch/gcc/expr.c @@ -7624,10 +7624,10 @@ expand_expr_real_2 (sepops ops, rtx targ if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) - expand_operands (treeop0, treeop1, subtarget, &op0, &op1, + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); else - expand_operands (treeop0, treeop1, subtarget, &op1, &op0, + expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0, EXPAND_NORMAL); goto binop3; } @@ -7645,7 +7645,8 @@ expand_expr_real_2 (sepops ops, rtx targ optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; - if (mode == GET_MODE_2XWIDER_MODE (innermode)) + if (mode == GET_MODE_2XWIDER_MODE (innermode) + && TREE_CODE (treeop0) != INTEGER_CST) { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { Index: gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c =================================================================== --- /dev/null +++ gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c @@ -0,0 +1,17 @@ +/* PR rtl-optimization/47299 */ + +extern void abort (void); + +__attribute__ ((noinline, noclone)) unsigned short +foo (unsigned char x) +{ + return x * 255; +} + +int +main () +{ + if (foo (0x40) != 0x3fc0) + abort (); + return 0; +}