Commit c613138b by Eric Botcazou Committed by Eric Botcazou

fold-const.c (extract_muldiv_1): Do not distribute a multiplication by a power-of-two value.

	* fold-const.c (extract_muldiv_1) <PLUS_EXPR>: Do not distribute a
	multiplication by a power-of-two value.
	(fold_plusminus_mult_expr): Use pow2p_hwi to spot a power-of-two value
	and turn the modulo operation into a masking operation.

From-SVN: r271963
parent 2098f8ec
2019-06-05 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (extract_muldiv_1) <PLUS_EXPR>: Do not distribute a
multiplication by a power-of-two value.
(fold_plusminus_mult_expr): Use pow2p_hwi to spot a power-of-two value
and turn the modulo operation into a masking operation.
2019-06-05 Jakub Jelinek <jakub@redhat.com> 2019-06-05 Jakub Jelinek <jakub@redhat.com>
PR debug/90733 PR debug/90733
......
...@@ -6475,8 +6475,12 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, ...@@ -6475,8 +6475,12 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
apply the distributive law to commute the multiply and addition apply the distributive law to commute the multiply and addition
if the multiplication of the constants doesn't overflow if the multiplication of the constants doesn't overflow
and overflow is defined. With undefined overflow and overflow is defined. With undefined overflow
op0 * c might overflow, while (op0 + orig_op1) * c doesn't. */ op0 * c might overflow, while (op0 + orig_op1) * c doesn't.
if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype)) But fold_plusminus_mult_expr would factor back any power-of-two
value so do not distribute in the first place in this case. */
if (code == MULT_EXPR
&& TYPE_OVERFLOW_WRAPS (ctype)
&& !(tree_fits_shwi_p (c) && pow2p_hwi (absu_hwi (tree_to_shwi (c)))))
return fold_build2 (tcode, ctype, return fold_build2 (tcode, ctype,
fold_build2 (code, ctype, fold_build2 (code, ctype,
fold_convert (ctype, op0), fold_convert (ctype, op0),
...@@ -7124,14 +7128,13 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type, ...@@ -7124,14 +7128,13 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type,
/* No identical multiplicands; see if we can find a common /* No identical multiplicands; see if we can find a common
power-of-two factor in non-power-of-two multiplies. This power-of-two factor in non-power-of-two multiplies. This
can help in multi-dimensional array access. */ can help in multi-dimensional array access. */
else if (tree_fits_shwi_p (arg01) else if (tree_fits_shwi_p (arg01) && tree_fits_shwi_p (arg11))
&& tree_fits_shwi_p (arg11))
{ {
HOST_WIDE_INT int01, int11, tmp; HOST_WIDE_INT int01 = tree_to_shwi (arg01);
HOST_WIDE_INT int11 = tree_to_shwi (arg11);
HOST_WIDE_INT tmp;
bool swap = false; bool swap = false;
tree maybe_same; tree maybe_same;
int01 = tree_to_shwi (arg01);
int11 = tree_to_shwi (arg11);
/* Move min of absolute values to int11. */ /* Move min of absolute values to int11. */
if (absu_hwi (int01) < absu_hwi (int11)) if (absu_hwi (int01) < absu_hwi (int11))
...@@ -7144,7 +7147,10 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type, ...@@ -7144,7 +7147,10 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type,
else else
maybe_same = arg11; maybe_same = arg11;
if (exact_log2 (absu_hwi (int11)) > 0 && int01 % int11 == 0 const unsigned HOST_WIDE_INT factor = absu_hwi (int11);
if (factor > 1
&& pow2p_hwi (factor)
&& (int01 & (factor - 1)) == 0
/* The remainder should not be a constant, otherwise we /* The remainder should not be a constant, otherwise we
end up folding i * 4 + 2 to (i * 2 + 1) * 2 which has end up folding i * 4 + 2 to (i * 2 + 1) * 2 which has
increased the number of multiplications necessary. */ increased the number of multiplications necessary. */
......
2019-06-05 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/discr6.ads: New test.
2019-06-05 Sam Tebbs <sam.tebbs@arm.com> 2019-06-05 Sam Tebbs <sam.tebbs@arm.com>
* gcc.target/aarch64/return_address_sign_b_1.c: New file. * gcc.target/aarch64/return_address_sign_b_1.c: New file.
......
-- { dg-do compile }
package Discr6 is
subtype Index_T is Integer range 0 .. 15;
type Arr is array (Index_T range <> ) of Long_Long_Integer;
type Rec2 (Size : Index_T := 2) is record
A : Arr (2 .. Size);
end record;
type Rec3 (D : Boolean := False) is record
R : Rec2;
case D is
when False=> null;
when True => I : Integer;
end case;
end record;
end Discr6;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment