aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-01-16 16:08:32 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-01-16 16:08:32 +0100
commit38943500babbfda935c1108a16ecbb03cb1a33e8 (patch)
tree8c56b282c07c85b373c44f431ced983c5995758c /gcc/fold-const.c
parent42b394ff00b100d2c968db6478c87a259333ccec (diff)
downloadgcc-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.c27
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));