diff options
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2dbca3f..a68b7b8 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9551,10 +9551,15 @@ fold_mult_zconjz (tree type, tree expr) 0 <= N < M as is common. In general, the precise value of P is unknown. M is chosen as large as possible such that constant N can be determined. - Returns M and sets *RESIDUE to N. */ + Returns M and sets *RESIDUE to N. + + If ALLOW_FUNC_ALIGN is true, do take functions' DECL_ALIGN_UNIT into + account. This is not always possible due to PR 35705. + */ static unsigned HOST_WIDE_INT -get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue) +get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, + bool allow_func_align) { enum tree_code code; @@ -9584,7 +9589,8 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue) } } - if (DECL_P (expr) && TREE_CODE (expr) != FUNCTION_DECL) + if (DECL_P (expr) + && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL)) return DECL_ALIGN_UNIT (expr); } else if (code == POINTER_PLUS_EXPR) @@ -9595,7 +9601,8 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue) op0 = TREE_OPERAND (expr, 0); STRIP_NOPS (op0); - modulus = get_pointer_modulus_and_residue (op0, residue); + modulus = get_pointer_modulus_and_residue (op0, residue, + allow_func_align); op1 = TREE_OPERAND (expr, 1); STRIP_NOPS (op1); @@ -11235,7 +11242,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) unsigned HOST_WIDE_INT modulus, residue; unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg1); - modulus = get_pointer_modulus_and_residue (arg0, &residue); + modulus = get_pointer_modulus_and_residue (arg0, &residue, + integer_onep (arg1)); /* This works because modulus is a power of 2. If this weren't the case, we'd have to replace it by its greatest power-of-2 |