diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-11 07:30:20 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-11 07:30:20 +0000 |
commit | 4debb32673b9a4f480ee333f812b28460ca80179 (patch) | |
tree | cfb012f8c9037ad4b63ec4f3e82cbc88f9a21773 /gcc | |
parent | a0ca7f3ded60c309d018df2b6f10a438bd30afe4 (diff) | |
download | gcc-4debb32673b9a4f480ee333f812b28460ca80179.tar.gz |
PR tree-optimization/56899
* fold-const.c (extract_muldiv_1): Apply distributive law
only if TYPE_OVERFLOW_WRAPS (ctype).
* gcc.c-torture/execute/pr56899.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197692 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr56899.c | 47 |
4 files changed, 62 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e1cc32176c..bab67ab7b01 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-04-11 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/56899 + * fold-const.c (extract_muldiv_1): Apply distributive law + only if TYPE_OVERFLOW_WRAPS (ctype). + 2013-04-11 Bin Cheng <bin.cheng@arm.com> PR target/56124 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index dcf7aa0d6a5..467b6d65619 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5850,8 +5850,10 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, /* The last case is if we are a multiply. In that case, we can apply the distributive law to commute the multiply and addition - if the multiplication of the constants doesn't overflow. */ - if (code == MULT_EXPR) + if the multiplication of the constants doesn't overflow + and overflow is defined. With undefined overflow + op0 * c might overflow, while (op0 + orig_op1) * c doesn't. */ + if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype)) return fold_build2 (tcode, ctype, fold_build2 (code, ctype, fold_convert (ctype, op0), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef84fe1a495..62557021bba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/56899 + * gcc.c-torture/execute/pr56899.c: New test. + 2013-04-10 David S. Miller <davem@davemloft.net> * gcc.target/sparc/setcc-4.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr56899.c b/gcc/testsuite/gcc.c-torture/execute/pr56899.c new file mode 100644 index 00000000000..9adf9af00ff --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr56899.c @@ -0,0 +1,47 @@ +/* PR tree-optimization/56899 */ + +#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8 +__attribute__((noinline, noclone)) void +f1 (int v) +{ + int x = -214748365 * (v - 1); + if (x != -1932735285) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f2 (int v) +{ + int x = 214748365 * (v + 1); + if (x != -1932735285) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f3 (unsigned int v) +{ + unsigned int x = -214748365U * (v - 1); + if (x != -1932735285U) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f4 (unsigned int v) +{ + unsigned int x = 214748365U * (v + 1); + if (x != -1932735285U) + __builtin_abort (); +} +#endif + +int +main () +{ +#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8 + f1 (10); + f2 (-10); + f3 (10); + f4 (-10U); +#endif + return 0; +} |