backport: re PR tree-optimization/56051 (Wrong expression evaluation)
Backported from mainline 2013-01-21 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/56051 * fold-const.c (fold_binary_loc): Don't fold X < (cast) (1 << Y) into (X >> Y) != 0 if cast is either a narrowing conversion, or widening conversion from signed to unsigned. * gcc.c-torture/execute/pr56051.c: New test. From-SVN: r195658
This commit is contained in:
parent
920debdb12
commit
daded9451f
|
@ -1,6 +1,14 @@
|
|||
2013-02-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
2013-01-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/56051
|
||||
* fold-const.c (fold_binary_loc): Don't fold
|
||||
X < (cast) (1 << Y) into (X >> Y) != 0 if cast is either
|
||||
a narrowing conversion, or widening conversion from signed
|
||||
to unsigned.
|
||||
|
||||
2013-01-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/56015
|
||||
|
|
|
@ -13453,10 +13453,22 @@ fold_binary_loc (location_t loc,
|
|||
TREE_OPERAND (arg1, 1)),
|
||||
build_int_cst (TREE_TYPE (arg0), 0));
|
||||
|
||||
/* Similarly for X < (cast) (1 << Y). But cast can't be narrowing,
|
||||
otherwise Y might be >= # of bits in X's type and thus e.g.
|
||||
(unsigned char) (1 << Y) for Y 15 might be 0.
|
||||
If the cast is widening, then 1 << Y should have unsigned type,
|
||||
otherwise if Y is number of bits in the signed shift type minus 1,
|
||||
we can't optimize this. E.g. (unsigned long long) (1 << Y) for Y
|
||||
31 might be 0xffffffff80000000. */
|
||||
if ((code == LT_EXPR || code == GE_EXPR)
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (arg0))
|
||||
&& CONVERT_EXPR_P (arg1)
|
||||
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
|
||||
&& (TYPE_PRECISION (TREE_TYPE (arg1))
|
||||
>= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0))))
|
||||
&& (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0)))
|
||||
|| (TYPE_PRECISION (TREE_TYPE (arg1))
|
||||
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))))
|
||||
&& integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
|
||||
{
|
||||
tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
2013-02-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
2013-01-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/56051
|
||||
* gcc.c-torture/execute/pr56051.c: New test.
|
||||
|
||||
2013-01-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/56015
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* PR tree-optimization/56051 */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned char x1[1] = { 0 };
|
||||
unsigned int s1 = __CHAR_BIT__;
|
||||
int a1 = x1[0] < (unsigned char) (1 << s1);
|
||||
unsigned char y1 = (unsigned char) (1 << s1);
|
||||
int b1 = x1[0] < y1;
|
||||
if (a1 != b1)
|
||||
abort ();
|
||||
#if __SIZEOF_LONG_LONG__ > __SIZEOF_INT__
|
||||
unsigned long long x2[1] = { 2ULL << (sizeof (int) * __CHAR_BIT__) };
|
||||
unsigned int s2 = sizeof (int) * __CHAR_BIT__ - 1;
|
||||
int a2 = x2[0] >= (unsigned long long) (1 << s2);
|
||||
unsigned long long y2 = 1 << s2;
|
||||
int b2 = x2[0] >= y2;
|
||||
if (a2 != b2)
|
||||
abort ();
|
||||
unsigned long long x3[1] = { 2ULL << (sizeof (int) * __CHAR_BIT__) };
|
||||
unsigned int s3 = sizeof (int) * __CHAR_BIT__ - 1;
|
||||
int a3 = x3[0] >= (unsigned long long) (1U << s3);
|
||||
unsigned long long y3 = 1U << s3;
|
||||
int b3 = x3[0] >= y3;
|
||||
if (a3 != b3)
|
||||
abort ();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue