diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-01-16 16:08:32 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-01-16 16:08:32 +0100 |
commit | 38943500babbfda935c1108a16ecbb03cb1a33e8 (patch) | |
tree | 8c56b282c07c85b373c44f431ced983c5995758c /gcc/fold-const.c | |
parent | 42b394ff00b100d2c968db6478c87a259333ccec (diff) | |
download | gcc-38943500babbfda935c1108a16ecbb03cb1a33e8.zip gcc-38943500babbfda935c1108a16ecbb03cb1a33e8.tar.gz gcc-38943500babbfda935c1108a16ecbb03cb1a33e8.tar.bz2 |
re PR c/83844 (ICE with warn_if_not_aligned attribute)
PR c/83844
* stor-layout.c (handle_warn_if_not_align): Use byte_position and
multiple_of_p instead of unchecked tree_to_uhwi and UHWI check.
If off is not INTEGER_CST, issue a may not be aligned warning
rather than isn't aligned. Use isn%'t rather than isn't.
* fold-const.c (multiple_of_p) <case BIT_AND_EXPR>: Don't fall through
into MULT_EXPR.
<case MULT_EXPR>: Improve the case when bottom and one of the
MULT_EXPR operands are INTEGER_CSTs and bottom is multiple of that
operand, in that case check if the other operand is multiple of
bottom divided by the INTEGER_CST operand.
* gcc.dg/pr83844.c: New test.
From-SVN: r256745
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5cf2052..1ea3766 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12595,9 +12595,34 @@ multiple_of_p (tree type, const_tree top, const_tree bottom) a multiple of BOTTOM then TOP is a multiple of BOTTOM. */ if (!integer_pow2p (bottom)) return 0; - /* FALLTHRU */ + return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom) + || multiple_of_p (type, TREE_OPERAND (top, 0), bottom)); case MULT_EXPR: + if (TREE_CODE (bottom) == INTEGER_CST) + { + op1 = TREE_OPERAND (top, 0); + op2 = TREE_OPERAND (top, 1); + if (TREE_CODE (op1) == INTEGER_CST) + std::swap (op1, op2); + if (TREE_CODE (op2) == INTEGER_CST) + { + if (multiple_of_p (type, op2, bottom)) + return 1; + /* Handle multiple_of_p ((x * 2 + 2) * 4, 8). */ + if (multiple_of_p (type, bottom, op2)) + { + widest_int w = wi::sdiv_trunc (wi::to_widest (bottom), + wi::to_widest (op2)); + if (wi::fits_to_tree_p (w, TREE_TYPE (bottom))) + { + op2 = wide_int_to_tree (TREE_TYPE (bottom), w); + return multiple_of_p (type, op1, op2); + } + } + return multiple_of_p (type, op1, bottom); + } + } return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom) || multiple_of_p (type, TREE_OPERAND (top, 0), bottom)); |