re PR tree-optimization/52286 (wrong code bug)
PR tree-optimization/52286 * fold-const.c (fold_binary_loc): For (X & C1) | C2 optimization use double_int_to_tree instead of build_int_cst_wide, rewrite to use double_int vars. * gcc.c-torture/execute/pr52286.c: New test. From-SVN: r184391
This commit is contained in:
parent
e992fc2e5d
commit
5a226e0af1
@ -1,3 +1,10 @@
|
||||
2012-02-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/52286
|
||||
* fold-const.c (fold_binary_loc): For (X & C1) | C2
|
||||
optimization use double_int_to_tree instead of build_int_cst_wide,
|
||||
rewrite to use double_int vars.
|
||||
|
||||
2012-02-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR target/50166
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Fold a constant sub-tree into a single node for C-compiler
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
|
||||
2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -10959,66 +10959,50 @@ fold_binary_loc (location_t loc,
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
{
|
||||
unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, hi3, lo3, mlo, mhi;
|
||||
double_int c1, c2, c3, msk;
|
||||
int width = TYPE_PRECISION (type), w;
|
||||
hi1 = TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1));
|
||||
lo1 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
|
||||
hi2 = TREE_INT_CST_HIGH (arg1);
|
||||
lo2 = TREE_INT_CST_LOW (arg1);
|
||||
c1 = tree_to_double_int (TREE_OPERAND (arg0, 1));
|
||||
c2 = tree_to_double_int (arg1);
|
||||
|
||||
/* If (C1&C2) == C1, then (X&C1)|C2 becomes (X,C2). */
|
||||
if ((hi1 & hi2) == hi1 && (lo1 & lo2) == lo1)
|
||||
if (double_int_equal_p (double_int_and (c1, c2), c1))
|
||||
return omit_one_operand_loc (loc, type, arg1,
|
||||
TREE_OPERAND (arg0, 0));
|
||||
TREE_OPERAND (arg0, 0));
|
||||
|
||||
if (width > HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
mhi = (unsigned HOST_WIDE_INT) -1
|
||||
>> (2 * HOST_BITS_PER_WIDE_INT - width);
|
||||
mlo = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mhi = 0;
|
||||
mlo = (unsigned HOST_WIDE_INT) -1
|
||||
>> (HOST_BITS_PER_WIDE_INT - width);
|
||||
}
|
||||
msk = double_int_mask (width);
|
||||
|
||||
/* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
|
||||
if ((~(hi1 | hi2) & mhi) == 0 && (~(lo1 | lo2) & mlo) == 0)
|
||||
if (double_int_zero_p (double_int_and_not (msk,
|
||||
double_int_ior (c1, c2))))
|
||||
return fold_build2_loc (loc, BIT_IOR_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0), arg1);
|
||||
TREE_OPERAND (arg0, 0), arg1);
|
||||
|
||||
/* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2,
|
||||
unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some
|
||||
mode which allows further optimizations. */
|
||||
hi1 &= mhi;
|
||||
lo1 &= mlo;
|
||||
hi2 &= mhi;
|
||||
lo2 &= mlo;
|
||||
hi3 = hi1 & ~hi2;
|
||||
lo3 = lo1 & ~lo2;
|
||||
c1 = double_int_and (c1, msk);
|
||||
c2 = double_int_and (c2, msk);
|
||||
c3 = double_int_and_not (c1, c2);
|
||||
for (w = BITS_PER_UNIT;
|
||||
w <= width && w <= HOST_BITS_PER_WIDE_INT;
|
||||
w <<= 1)
|
||||
{
|
||||
unsigned HOST_WIDE_INT mask
|
||||
= (unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - w);
|
||||
if (((lo1 | lo2) & mask) == mask
|
||||
&& (lo1 & ~mask) == 0 && hi1 == 0)
|
||||
if (((c1.low | c2.low) & mask) == mask
|
||||
&& (c1.low & ~mask) == 0 && c1.high == 0)
|
||||
{
|
||||
hi3 = 0;
|
||||
lo3 = mask;
|
||||
c3 = uhwi_to_double_int (mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hi3 != hi1 || lo3 != lo1)
|
||||
if (!double_int_equal_p (c3, c1))
|
||||
return fold_build2_loc (loc, BIT_IOR_EXPR, type,
|
||||
fold_build2_loc (loc, BIT_AND_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0),
|
||||
build_int_cst_wide (type,
|
||||
lo3, hi3)),
|
||||
arg1);
|
||||
fold_build2_loc (loc, BIT_AND_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0),
|
||||
double_int_to_tree (type,
|
||||
c3)),
|
||||
arg1);
|
||||
}
|
||||
|
||||
/* (X & Y) | Y is (X, Y). */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-02-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/52286
|
||||
* gcc.c-torture/execute/pr52286.c: New test.
|
||||
|
||||
2012-02-18 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/52295
|
||||
|
14
gcc/testsuite/gcc.c-torture/execute/pr52286.c
Normal file
14
gcc/testsuite/gcc.c-torture/execute/pr52286.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* PR tree-optimization/52286 */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int a, b;
|
||||
asm ("" : "=r" (a) : "0" (0));
|
||||
b = (~a | 1) & -2038094497;
|
||||
if (b >= 0)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user