Commit d1f2bea5 by Segher Boessenkool Committed by Segher Boessenkool

powerpc: Handle DImode rotatert implemented with rlwinm (PR69946)

Some DImode rotate-right-and-mask can be implemented best with a rlwinm
instruction: those that could be a lshiftrt instead of a rotatert, while
the mask is not right-aligned.  Why the rotate in the testcase is not
optimised to a plain shift is another question, but we need to handle
it here anyway.  We compute the shift amount for a 64-bit rotate.  This
is 32 too high in this case; if we print using %h that is masked out (and
this doesn't silently let through invalid instructions, everything is
checked by rs6000_is_valid_shift_mask which is much more thorough).


	PR target/69946
	* config/rs6000/rs6000.c (rs6000_insn_for_shift_mask): Print rlwinm
	shift amount using %h.  Add comment.

gcc/testsuite/
	* gcc.target/powerpc/pr69946.c: New file.

From-SVN: r233755
parent 4a4f9d2b
2016-02-26 Segher Boessenkool <segher@kernel.crashing.org>
PR target/69946
* config/rs6000/rs6000.c (rs6000_insn_for_shift_mask): Print rlwinm
shift amount using %h. Add comment.
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
......
......@@ -17438,9 +17438,12 @@ rs6000_insn_for_shift_mask (machine_mode mode, rtx *operands, bool dot)
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[3] = GEN_INT (31 - nb);
operands[4] = GEN_INT (31 - ne);
/* This insn can also be a 64-bit rotate with mask that really makes
it just a shift right (with mask); the %h below are to adjust for
that situation (shift count is >= 32 in that case). */
if (dot)
return "rlw%I2nm. %0,%1,%2,%3,%4";
return "rlw%I2nm %0,%1,%2,%3,%4";
return "rlw%I2nm. %0,%1,%h2,%3,%4";
return "rlw%I2nm %0,%1,%h2,%3,%4";
}
gcc_unreachable ();
2016-02-26 Segher Boessenkool <segher@kernel.crashing.org>
PR target/69946
* gcc.target/powerpc/pr69946.c: New file.
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
......
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc_elfv2 } } */
/* { dg-options "-O2" } */
/* This generates a rotate:DI by 44, with mask 0xf00, which is implemented
using a rlwinm instruction. We used to write 44 for the shift count
there; it should be 12. */
struct A
{
int a : 4;
int : 2;
int b : 2;
int : 2;
int c : 2;
int d : 1;
int e;
};
struct B
{
int a : 4;
} *a;
void bar (struct A);
void
foo (void)
{
struct B b = a[0];
struct A c;
c.a = b.a;
c.b = 1;
c.c = 1;
c.d = 0;
bar (c);
}
/* { dg-final { scan-assembler-not {(?n)rlwinm.*,44,20,23} } } */
/* { dg-final { scan-assembler-times {(?n)rlwinm.*,12,20,23} 1 } } */
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