diff mbox

Fix big-endian bswap

Message ID HE1PR0801MB1482D3151EBD44465B472D46832D0@HE1PR0801MB1482.eurprd08.prod.outlook.com
State New
Headers show

Commit Message

Wilco Dijkstra June 23, 2016, 4:34 p.m. UTC
This patch fixes a bug in the bswap pass.  In big-endian BIT_FIELD_REF uses
big-endian bit numbering so we need to adjust the bit position.
The existing version could potentially generate incorrect code however GCC doesn't
emit a BIT_FIELD_REF to access the low byte in a register, so the symbolic number
never matches in big-endian.

The test gcc.dg/optimize-bswapsi-4.c now passes on AArch64, no other changes.
OK for commit?

ChangeLog:
2016-06-23  Wilco Dijkstra  <wdijkstr@arm.com>

	* gcc/tree-ssa-math-opts.c (find_bswap_or_nop_1): Adjust bitnumbering
	for big-endian BIT_FIELD_REF.

--

Comments

Richard Biener June 28, 2016, 1:37 p.m. UTC | #1
On Thu, Jun 23, 2016 at 6:34 PM, Wilco Dijkstra <Wilco.Dijkstra@arm.com> wrote:
> This patch fixes a bug in the bswap pass.  In big-endian BIT_FIELD_REF uses
> big-endian bit numbering so we need to adjust the bit position.
> The existing version could potentially generate incorrect code however GCC doesn't
> emit a BIT_FIELD_REF to access the low byte in a register, so the symbolic number
> never matches in big-endian.
>
> The test gcc.dg/optimize-bswapsi-4.c now passes on AArch64, no other changes.
> OK for commit?

Ok.

Thanks,
Richard.

> ChangeLog:
> 2016-06-23  Wilco Dijkstra  <wdijkstr@arm.com>
>
>         * gcc/tree-ssa-math-opts.c (find_bswap_or_nop_1): Adjust bitnumbering
>         for big-endian BIT_FIELD_REF.
>
> --
> diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> index 513ef0b3f4eb29a35eae8a0eb14ee8f8c24fcfd9..d31c12fd818a713ca3d251b9464015b147235bbe 100644
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -2307,6 +2307,10 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
>           && bitsize % BITS_PER_UNIT == 0
>           && init_symbolic_number (n, TREE_OPERAND (rhs1, 0)))
>         {
> +         /* Handle big-endian bit numbering in BIT_FIELD_REF.  */
> +         if (BYTES_BIG_ENDIAN)
> +           bitpos = TYPE_PRECISION (n->type) - bitpos - bitsize;
> +
>           /* Shift.  */
>           if (!do_shift_rotate (RSHIFT_EXPR, n, bitpos))
>             return NULL;
>
diff mbox

Patch

diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 513ef0b3f4eb29a35eae8a0eb14ee8f8c24fcfd9..d31c12fd818a713ca3d251b9464015b147235bbe 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2307,6 +2307,10 @@  find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
 	  && bitsize % BITS_PER_UNIT == 0
 	  && init_symbolic_number (n, TREE_OPERAND (rhs1, 0)))
 	{
+	  /* Handle big-endian bit numbering in BIT_FIELD_REF.  */
+	  if (BYTES_BIG_ENDIAN)
+	    bitpos = TYPE_PRECISION (n->type) - bitpos - bitsize;
+
 	  /* Shift.  */
 	  if (!do_shift_rotate (RSHIFT_EXPR, n, bitpos))
 	    return NULL;