Submitter | Bernd Schmidt |
---|---|

Date | Aug. 2, 2010, 8:37 p.m. |

Message ID | <4C572CA0.3040802@codesourcery.com> |

Download | mbox | patch |

Permalink | /patch/60665/ |

State | New |

Headers | show |

## Comments

On 08/02/2010 10:37 PM, Bernd Schmidt wrote: > + if (GET_CODE (op0) == NEG && CONST_INT_P (trueop1)) > + return simplify_gen_binary (MULT, mode, XEXP (op0, 0), > + simplify_gen_unary (NEG, mode, op1, mode)); Why not go one step further and try it on all operands: if (GET_CODE (op0) == NEG) { rtx temp = simplify_unary (NEG, mode, op1, mode); if (temp) return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp); } if (GET_CODE (op1) == NEG) { rtx temp = simplify_unary (NEG, mode, op0, mode); if (temp) return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0)); } Paolo

> * config/arm/constraints.md (M): Examine only 32 bits of a > HOST_WIDE_INT. > * config/arm/predicates.md (power_of_two_operand): Likewise. Is this left over from before you fixed the GEN_INT to be trunc_int_for_mode? This doesn't seem right... r~

On 08/03/2010 06:05 PM, Richard Henderson wrote: >> * config/arm/constraints.md (M): Examine only 32 bits of a >> HOST_WIDE_INT. >> * config/arm/predicates.md (power_of_two_operand): Likewise. > > Is this left over from before you fixed the GEN_INT to > be trunc_int_for_mode? This doesn't seem right... Why not? The problem is (1 << 31), which is a power of two, but negative in SImode and fails the test if sizeof HOST_WIDE_INT > 32. It's actually needed _after_ fixing the GEN_INT. Bernd

On 08/03/2010 09:09 AM, Bernd Schmidt wrote: > On 08/03/2010 06:05 PM, Richard Henderson wrote: >>> * config/arm/constraints.md (M): Examine only 32 bits of a >>> HOST_WIDE_INT. >>> * config/arm/predicates.md (power_of_two_operand): Likewise. >> >> Is this left over from before you fixed the GEN_INT to >> be trunc_int_for_mode? This doesn't seem right... > > Why not? The problem is (1 << 31), which is a power of two, but > negative in SImode and fails the test if sizeof HOST_WIDE_INT > 32. > It's actually needed _after_ fixing the GEN_INT. Ah, ok. r~

## Patch

Index: config/arm/constraints.md =================================================================== --- config/arm/constraints.md (revision 162821) +++ config/arm/constraints.md (working copy) @@ -121,7 +121,7 @@ (define_constraint "M" "In Thumb-1 state a constant that is a multiple of 4 in the range 0-1020." (and (match_code "const_int") (match_test "TARGET_32BIT ? ((ival >= 0 && ival <= 32) - || ((ival & (ival - 1)) == 0)) + || (((ival & (ival - 1)) & 0xFFFFFFFF) == 0)) : ival >= 0 && ival <= 1020 && (ival & 3) == 0"))) (define_constraint "N" Index: config/arm/predicates.md =================================================================== --- config/arm/predicates.md (revision 162821) +++ config/arm/predicates.md (working copy) @@ -289,7 +289,7 @@ (define_special_predicate "arm_reg_or_ex (define_predicate "power_of_two_operand" (match_code "const_int") { - HOST_WIDE_INT value = INTVAL (op); + unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff; return value != 0 && (value & (value - 1)) == 0; }) Index: simplify-rtx.c =================================================================== --- simplify-rtx.c (revision 162821) +++ simplify-rtx.c (working copy) @@ -2109,6 +2109,10 @@ simplify_binary_operation_1 (enum rtx_co if (trueop1 == constm1_rtx) return simplify_gen_unary (NEG, mode, op0, mode); + if (GET_CODE (op0) == NEG && CONST_INT_P (trueop1)) + return simplify_gen_binary (MULT, mode, XEXP (op0, 0), + simplify_gen_unary (NEG, mode, op1, mode)); + /* Maybe simplify x * 0 to 0. The reduction is not valid if x is NaN, since x * 0 is then also NaN. Nor is it valid when the mode has signed zeros, since multiplying a negative Index: combine.c =================================================================== --- combine.c (revision 162821) +++ combine.c (working copy) @@ -7110,10 +7110,46 @@ make_compound_operation (rtx x, enum rtx && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT && INTVAL (XEXP (x, 1)) >= 0) { + HOST_WIDE_INT count = INTVAL (XEXP (x, 1)); + HOST_WIDE_INT multval = (HOST_WIDE_INT) 1 << count; + new_rtx = make_compound_operation (XEXP (x, 0), next_code); - new_rtx = gen_rtx_MULT (mode, new_rtx, - GEN_INT ((HOST_WIDE_INT) 1 - << INTVAL (XEXP (x, 1)))); + if (GET_CODE (new_rtx) == NEG) + { + new_rtx = XEXP (new_rtx, 0); + multval = -multval; + } + multval = trunc_int_for_mode (multval, mode); + new_rtx = gen_rtx_MULT (mode, new_rtx, GEN_INT (multval)); + } + break; + + case PLUS: + lhs = XEXP (x, 0); + rhs = XEXP (x, 1); + lhs = make_compound_operation (lhs, MEM); + rhs = make_compound_operation (rhs, MEM); + if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG + && SCALAR_INT_MODE_P (mode)) + { + tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (lhs, 0), 0), + XEXP (lhs, 1)); + new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem); + } + else if (GET_CODE (lhs) == MULT + && (CONST_INT_P (XEXP (lhs, 1)) && INTVAL (XEXP (lhs, 1)) < 0)) + { + tem = simplify_gen_binary (MULT, mode, XEXP (lhs, 0), + simplify_gen_unary (NEG, mode, + XEXP (lhs, 1), + mode)); + new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem); + } + else + { + SUBST (XEXP (x, 0), lhs); + SUBST (XEXP (x, 1), rhs); + goto maybe_swap; } break; @@ -7345,6 +7381,7 @@ make_compound_operation (rtx x, enum rtx SUBST (XVECEXP (x, i, j), new_rtx); } + maybe_swap: /* If this is a commutative operation, the changes to the operands may have made it noncanonical. */ if (COMMUTATIVE_ARITH_P (x)