mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 08:13:58 +08:00
re PR middle-end/24427 (missing optimization opportunity with binary operators)
PR middle-end/24427 * fold-const.c (fold_binary) <BIT_IOR_EXPR>: Transform (X&C1)|C2 into (X,C2) if C1 is a subset of the bits of C2. Transform (X&C1)|C2 into X|C2 if C1|C2 == ~0. Canonicalize (X&C1)|C2 as (X&(C1&~C2))|C2. <BIT_AND_EXPR>: Canonicalize (X|C1)&C2 as (X&C2)|(C1&C2). * gcc.dg/tree-ssa/andor-1.c: New test case. From-SVN: r110918
This commit is contained in:
parent
4c553323a6
commit
840992bdc2
@ -1,3 +1,12 @@
|
||||
2006-02-13 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR middle-end/24427
|
||||
* fold-const.c (fold_binary) <BIT_IOR_EXPR>: Transform (X&C1)|C2
|
||||
into (X,C2) if C1 is a subset of the bits of C2. Transform
|
||||
(X&C1)|C2 into X|C2 if C1|C2 == ~0. Canonicalize (X&C1)|C2 as
|
||||
(X&(C1&~C2))|C2.
|
||||
<BIT_AND_EXPR>: Canonicalize (X|C1)&C2 as (X&C2)|(C1&C2).
|
||||
|
||||
2006-02-13 Josh Conner <jconner@apple.com>
|
||||
|
||||
PR target/25376
|
||||
|
@ -8114,6 +8114,53 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
return omit_one_operand (type, t1, arg0);
|
||||
}
|
||||
|
||||
/* Canonicalize (X & C1) | C2. */
|
||||
if (TREE_CODE (arg0) == BIT_AND_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
{
|
||||
unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, mlo, mhi;
|
||||
int width = TYPE_PRECISION (type);
|
||||
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);
|
||||
|
||||
/* If (C1&C2) == C1, then (X&C1)|C2 becomes (X,C2). */
|
||||
if ((hi1 & hi2) == hi1 && (lo1 & lo2) == lo1)
|
||||
return omit_one_operand (type, arg1, 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);
|
||||
}
|
||||
|
||||
/* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
|
||||
if ((~(hi1 | hi2) & mhi) == 0 && (~(lo1 | lo2) & mlo) == 0)
|
||||
return fold_build2 (BIT_IOR_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0), arg1);
|
||||
|
||||
/* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2. */
|
||||
hi1 &= mhi;
|
||||
lo1 &= mlo;
|
||||
if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1)
|
||||
return fold_build2 (BIT_IOR_EXPR, type,
|
||||
fold_build2 (BIT_AND_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0),
|
||||
build_int_cst_wide (type,
|
||||
lo1 & ~lo2,
|
||||
hi1 & ~hi2)),
|
||||
arg1);
|
||||
}
|
||||
|
||||
t1 = distribute_bit_expr (code, type, arg0, arg1);
|
||||
if (t1 != NULL_TREE)
|
||||
return t1;
|
||||
@ -8256,6 +8303,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
|
||||
return omit_one_operand (type, integer_zero_node, arg0);
|
||||
|
||||
/* Canonicalize (X | C1) & C2 as (X & C2) | (C1 & C2). */
|
||||
if (TREE_CODE (arg0) == BIT_IOR_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
return fold_build2 (BIT_IOR_EXPR, type,
|
||||
fold_build2 (BIT_AND_EXPR, type,
|
||||
TREE_OPERAND (arg0, 0), arg1),
|
||||
fold_build2 (BIT_AND_EXPR, type,
|
||||
TREE_OPERAND (arg0, 1), arg1));
|
||||
|
||||
t1 = distribute_bit_expr (code, type, arg0, arg1);
|
||||
if (t1 != NULL_TREE)
|
||||
return t1;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-02-13 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR middle-end/24427
|
||||
* gcc.dg/tree-ssa/andor-1.c: New test case.
|
||||
|
||||
2006-02-13 Josh Conner <jconner@apple.com>
|
||||
|
||||
PR target/25376
|
||||
|
65
gcc/testsuite/gcc.dg/tree-ssa/andor-1.c
Normal file
65
gcc/testsuite/gcc.dg/tree-ssa/andor-1.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-original" } */
|
||||
|
||||
unsigned int test1(unsigned int a)
|
||||
{
|
||||
return (a & 1) | 1;
|
||||
}
|
||||
|
||||
int test2(int b)
|
||||
{
|
||||
return (b & 1) | 1;
|
||||
}
|
||||
|
||||
unsigned int test3(unsigned int c)
|
||||
{
|
||||
return (c | 1) & 1;
|
||||
}
|
||||
|
||||
int test4(int d)
|
||||
{
|
||||
return (d | 1) & 1;
|
||||
}
|
||||
|
||||
unsigned int test5(unsigned int e)
|
||||
{
|
||||
return (e | 4) & 6;
|
||||
}
|
||||
|
||||
int test6(int f)
|
||||
{
|
||||
return (f | 4) & 6;
|
||||
}
|
||||
|
||||
unsigned int test7(unsigned int g)
|
||||
{
|
||||
return (g & -2) | 1;
|
||||
}
|
||||
|
||||
int test8(int h)
|
||||
{
|
||||
return (h & -2) | 1;
|
||||
}
|
||||
|
||||
unsigned int test9(unsigned int i)
|
||||
{
|
||||
return (i & 3) | 1;
|
||||
}
|
||||
|
||||
int test10(int j)
|
||||
{
|
||||
return (j & 3) | 1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "a \& 1 \\| 1" 0 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "b \& 1 \\| 1" 0 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "\\(c \\| 1\\) \& 1" 0 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "\\(d \\| 1\\) \& 1" 0 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "e \& 2 \\| 4" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "f \& 2 \\| 4" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "g \\| 1" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "h \\| 1" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "i \& 2 \\| 1" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "j \& 2 \\| 1" 1 "original" } } */
|
||||
/* { dg-final { cleanup-tree-dump "original" } } */
|
||||
|
Loading…
Reference in New Issue
Block a user