Commit e215422f by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/84982 (logically inverting bools into local array…

re PR tree-optimization/84982 (logically inverting bools into local array results in bitwise negation)

	PR tree-optimization/84982
	* gimple-ssa-store-merging.c (invert_op): Handle boolean inversion
	by flipping the least significant bit rather than all bits from
	bitpos to bitpos + bitsize - 1.

	* c-c++-common/pr84982.c: New test.

From-SVN: r258742
parent 57e20f74
2018-03-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/84982
* gimple-ssa-store-merging.c (invert_op): Handle boolean inversion
by flipping the least significant bit rather than all bits from
bitpos to bitpos + bitsize - 1.
2018-03-21 Nathan Sidwell <nathan@acm.org>
* doc/extend.texi (Deprecated Features): Remove mention of
......
......@@ -3248,16 +3248,23 @@ invert_op (split_store *split_store, int idx, tree int_type, tree &mask)
unsigned int i;
store_immediate_info *info;
unsigned int cnt = 0;
bool any_paddings = false;
FOR_EACH_VEC_ELT (split_store->orig_stores, i, info)
{
bool bit_not_p = idx < 2 ? info->ops[idx].bit_not_p : info->bit_not_p;
if (bit_not_p)
++cnt;
{
++cnt;
tree lhs = gimple_assign_lhs (info->stmt);
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
&& TYPE_PRECISION (TREE_TYPE (lhs)) < info->bitsize)
any_paddings = true;
}
}
mask = NULL_TREE;
if (cnt == 0)
return NOP_EXPR;
if (cnt == split_store->orig_stores.length ())
if (cnt == split_store->orig_stores.length () && !any_paddings)
return BIT_NOT_EXPR;
unsigned HOST_WIDE_INT try_bitpos = split_store->bytepos * BITS_PER_UNIT;
......@@ -3274,14 +3281,42 @@ invert_op (split_store *split_store, int idx, tree int_type, tree &mask)
clear regions with !bit_not_p, so that gaps in between stores aren't
set in the mask. */
unsigned HOST_WIDE_INT bitsize = info->bitsize;
unsigned HOST_WIDE_INT prec = bitsize;
unsigned int pos_in_buffer = 0;
if (any_paddings)
{
tree lhs = gimple_assign_lhs (info->stmt);
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
&& TYPE_PRECISION (TREE_TYPE (lhs)) < bitsize)
prec = TYPE_PRECISION (TREE_TYPE (lhs));
}
if (info->bitpos < try_bitpos)
{
gcc_assert (info->bitpos + bitsize > try_bitpos);
bitsize -= (try_bitpos - info->bitpos);
if (!BYTES_BIG_ENDIAN)
{
if (prec <= try_bitpos - info->bitpos)
continue;
prec -= try_bitpos - info->bitpos;
}
bitsize -= try_bitpos - info->bitpos;
if (BYTES_BIG_ENDIAN && prec > bitsize)
prec = bitsize;
}
else
pos_in_buffer = info->bitpos - try_bitpos;
if (prec < bitsize)
{
/* If this is a bool inversion, invert just the least significant
prec bits rather than all bits of it. */
if (BYTES_BIG_ENDIAN)
{
pos_in_buffer += bitsize - prec;
if (pos_in_buffer >= split_store->size)
continue;
}
bitsize = prec;
}
if (pos_in_buffer + bitsize > split_store->size)
bitsize = split_store->size - pos_in_buffer;
unsigned char *p = buf + (pos_in_buffer / BITS_PER_UNIT);
......
2018-03-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/84982
* c-c++-common/pr84982.c: New test.
PR c++/84961
* c-c++-common/pr43690.c: Don't expect errors on "m" (--x) and
"m" (++x) in C++.
......
/* PR tree-optimization/84982 */
/* { dg-do run } */
/* { dg-options "-O2" } */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#endif
struct S { bool a, b, c, d; };
__attribute__((noipa)) void
bar (bool *x)
{
if (x[0] || !x[1] || !x[2] || x[3])
__builtin_abort ();
}
__attribute__((noipa)) void
foo (struct S *x)
{
bool a[4];
a[0] = !x->a;
a[1] = !x->b;
a[2] = x->c;
a[3] = !x->d;
bar (a);
}
int
main ()
{
struct S s;
s.a = true; s.b = false; s.c = true; s.d = true;
foo (&s);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment