re PR target/16457 (PowerPC - Combine two rldicr instructions into a single rlwinm.)

.:	PR target/16457
	* config/rs6000/rs6000.c (mask64_2_operand): Stub to call
	mask64_1or2_operand.
	(mask64_1or_2_operand): Broken out of mask64_2_operand, add flag
	to spot rlwinm opportunities.
	(and64_2_operand): Use mask_1or2_operand.
	* config/rs6000/rs6000.md (anddi3): Use rlwinm when possible.
testsuite:
	PR target/16457
	* gcc.dg/ppc-and-1: New

From-SVN: r90481
This commit is contained in:
Nathan Sidwell 2004-11-11 17:03:36 +00:00 committed by Nathan Sidwell
parent 00803cd56f
commit e1e2e653d7
5 changed files with 64 additions and 17 deletions

View file

@ -1,3 +1,13 @@
2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
PR target/16457
* config/rs6000/rs6000.c (mask64_2_operand): Stub to call
mask64_1or2_operand.
(mask64_1or2_operand): Broken out of mask64_2_operand, add flag
to spot rlwinm opportunities.
(and64_2_operand): Use mask_1or2_operand.
* config/rs6000/rs6000.md (anddi3): Use rlwinm when possible.
2004-11-11 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (update_phi_nodes_for_guard): Call reverse_phis.

View file

@ -2708,23 +2708,26 @@ mask64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
}
/* Like mask64_operand, but allow up to three transitions. This
predicate is used by insn patterns that generate two rldicl or
rldicr machine insns. */
int
mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
static int
mask64_1or2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED,
bool allow_one)
{
if (GET_CODE (op) == CONST_INT)
{
HOST_WIDE_INT c, lsb;
bool one_ok;
c = INTVAL (op);
/* Disallow all zeros. */
if (c == 0)
return 0;
/* We can use a single rlwinm insn if no upper bits of C are set
AND there are zero, one or two transitions in the _whole_ of
C. */
one_ok = !(c & ~(HOST_WIDE_INT)0xffffffff);
/* We don't change the number of transitions by inverting,
so make sure we start with the LS bit zero. */
if (c & 1)
@ -2748,6 +2751,9 @@ mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
/* Erase second transition. */
c &= -lsb;
if (one_ok && !(allow_one || c))
return 0;
/* Find the third transition (if any). */
lsb = c & -c;
@ -2757,6 +2763,14 @@ mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
}
/* Like mask64_operand, but allow up to three transitions. This
predicate is used by insn patterns that generate two rldicl or
rldicr machine insns. */
int mask64_2_operand (rtx op, enum machine_mode mode)
{
return mask64_1or2_operand (op, mode, false);
}
/* Generates shifts and masks for a pair of rldicl or rldicr insns to
implement ANDing by the mask IN. */
void
@ -2846,9 +2860,9 @@ int
and64_2_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
return gpc_reg_operand (op, mode) || mask64_1or2_operand (op, mode, true);
return logical_operand (op, mode) || mask64_2_operand (op, mode);
return logical_operand (op, mode) || mask64_1or2_operand (op, mode, true);
}
/* Return 1 if the operand is either a non-special register or a

View file

@ -7197,19 +7197,20 @@
"")
(define_insn "anddi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "?r,S,K,J,t")))
(clobber (match_scratch:CC 3 "=X,X,x,x,X"))]
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t")))
(clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))]
"TARGET_POWERPC64"
"@
and %0,%1,%2
rldic%B2 %0,%1,0,%S2
rlwinm %0,%1,0,%m2,%M2
andi. %0,%1,%b2
andis. %0,%1,%u2
#"
[(set_attr "type" "*,*,compare,compare,*")
(set_attr "length" "4,4,4,4,8")])
[(set_attr "type" "*,*,*,compare,compare,*")
(set_attr "length" "4,4,4,4,4,8")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@ -7227,10 +7228,9 @@
(and:DI (rotate:DI (match_dup 0)
(match_dup 6))
(match_dup 7)))]
"
{
build_mask64_2_operands (operands[2], &operands[4]);
}")
})
(define_insn "*anddi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y")

View file

@ -1,5 +1,8 @@
2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
PR target/16457
* gcc.dg/ppc-and-1: New
PR target/16796
* gcc.dg/ppc-mov-1.c: New.

View file

@ -0,0 +1,20 @@
/* { dg-do compile { target powerpc64-*-* } } */
/* { dg-options "-m64 -O2" } */
/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,0,30" } } */
/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,29,30" } } */
/* { dg-final { scan-assembler-not "rldicr" } } */
/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */
/* PR 16457 - use rlwinm insn. */
char *foo1 (char *p, unsigned int x)
{
return p - (x & ~1);
}
char *foo2 (char *p, unsigned int x)
{
return p - (x & 6);
}