From fd3e569d5e3d770007516de58e70dd0f23dd07ed Mon Sep 17 00:00:00 2001 From: jakub Date: Wed, 5 Dec 2007 22:24:08 +0000 Subject: [PATCH] PR middle-end/34337 * fold-const.c (fold_binary) : Don't minimize number of bits set in C1 if a mode mask for some mode can be used instead. * gcc.c-torture/execute/20071205-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130635 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++++ gcc/fold-const.c | 31 +++++++++++++++++++----- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/execute/20071205-1.c | 17 +++++++++++++ 4 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20071205-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da6a6c3..189286b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-12-05 Jakub Jelinek + + PR middle-end/34337 + * fold-const.c (fold_binary) : Don't minimize + number of bits set in C1 if a mode mask for some mode can be used + instead. + 2007-12-05 Bernhard Fischer * varasm.c (merge_weak, weak_finish, assemble_alias): Commentary typo diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1502994..8519e68 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10570,8 +10570,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && 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); + unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, hi3, lo3, mlo, mhi; + 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); @@ -10599,16 +10599,35 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) 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. */ + /* 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; - if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1) + hi2 &= mhi; + lo2 &= mlo; + hi3 = hi1 & ~hi2; + lo3 = lo1 & ~lo2; + 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) + { + hi3 = 0; + lo3 = mask; + break; + } + } + if (hi3 != hi1 || lo3 != 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)), + lo3, hi3)), arg1); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1acb944..70aa1df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-12-05 Jakub Jelinek + + PR middle-end/34337 + * gcc.c-torture/execute/20071205-1.c: New test. + 2007-12-05 Kaz Kojima * gfortran.dg/module_nan.f90: Add -mieee for sh. diff --git a/gcc/testsuite/gcc.c-torture/execute/20071205-1.c b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c new file mode 100644 index 0000000..fa19ec0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c @@ -0,0 +1,17 @@ +/* PR middle-end/34337 */ + +extern void abort (void); + +int +foo (int x) +{ + return ((x << 8) & 65535) | 255; +} + +int +main (void) +{ + if (foo (0x32) != 0x32ff || foo (0x174) != 0x74ff) + abort (); + return 0; +} -- 2.7.4