#ifdef MUST_ALIGN
- if (GET_CODE (size) == CONST_INT)
- size = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (size) + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1));
- else
- size = expand_binop (Pmode, add_optab, size,
- gen_rtx (CONST_INT, VOIDmode,
- BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
- 0, 1, OPTAB_LIB_WIDEN);
+ if (known_align % BIGGEST_ALIGNMENT != 0)
+ {
+ if (GET_CODE (size) == CONST_INT)
+ size = gen_rtx (CONST_INT, VOIDmode,
+ (INTVAL (size)
+ + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1)));
+ else
+ size = expand_binop (Pmode, add_optab, size,
+ gen_rtx (CONST_INT, VOIDmode,
+ BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
+ 0, 1, OPTAB_LIB_WIDEN);
+ }
#endif
#ifdef SETJMP_VIA_SAVE_AREA
return non_lvalue (convert (type, arg0));
if (integer_zerop (arg1))
return t;
+
+ /* If we have ((a * C1) / C2) and C1 % C2 == 0, we can replace this with
+ (a * (C1/C2). Also look for when we have a SAVE_EXPR in
+ between. */
+ if (TREE_CODE (arg1) == INTEGER_CST
+ && TREE_INT_CST_LOW (arg1) > 0 && TREE_INT_CST_HIGH (arg1) == 0
+ && TREE_CODE (arg0) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
+ && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) > 0
+ && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
+ && 0 == (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
+ % TREE_INT_CST_LOW (arg1)))
+ {
+ tree new_op
+ = build_int_2 (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
+ / TREE_INT_CST_LOW (arg1));
+
+ TREE_TYPE (new_op) = type;
+ return build (MULT_EXPR, type, TREE_OPERAND (arg0, 0), new_op);
+ }
+
+ else if (TREE_CODE (arg1) == INTEGER_CST
+ && TREE_INT_CST_LOW (arg1) > 0 && TREE_INT_CST_HIGH (arg1) == 0
+ && TREE_CODE (arg0) == SAVE_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == MULT_EXPR
+ && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
+ == INTEGER_CST)
+ && (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
+ > 0)
+ && (TREE_INT_CST_HIGH (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
+ == 0)
+ && (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
+ % TREE_INT_CST_LOW (arg1)) == 0)
+ {
+ tree new_op
+ = build_int_2 (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
+ / TREE_INT_CST_LOW (arg1));
+
+ TREE_TYPE (new_op) = type;
+ return build (MULT_EXPR, type,
+ TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), new_op);
+ }
+
#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
#ifndef REAL_INFINITY
if (TREE_CODE (arg1) == REAL_CST
else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG)
{
rtx x = emit_insn_before (gen_move_insn (reloadreg, in), before_insn);
- if (is_asm && recog_memoized (x) < 0)
+ if (is_asm
+ && (recog_memoized (x) < 0
+ || (insn_extract (x), ! constrain_operands (INSN_CODE (x), 1))))
{
delete_insn (x);
return 0;
{
rtx x = emit_insn_before (gen_reload_load_address (reloadreg, in),
before_insn);
- if (is_asm && recog_memoized (x) < 0)
+ if (is_asm
+ && (recog_memoized (x) < 0
+ || (insn_extract (x), ! constrain_operands (INSN_CODE (x), 1))))
{
delete_insn (x);
return 0;
{
rtx x = emit_insn_before (gen_rtx (SET, VOIDmode, reloadreg, in),
before_insn);
- if (is_asm && recog_memoized (x) < 0)
+ if (is_asm
+ && (recog_memoized (x) < 0
+ || (insn_extract (x), ! constrain_operands (INSN_CODE (x), 1))))
{
delete_insn (x);
return 0;