This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Tweak (long long)x >> 63 in i386.c


The following patch is a minor tweak to i386.c's ix86_split_ashrdi to
improve the code we generate to arithmetic right shift a DImode value
by 63 bits.

For the following testcase,

long long foo(long long x)
{
  return x >> 63;
}

On x86, mainline generates the following with "-O2 -fomit-frame-pointer"

foo:    movl    8(%esp), %edx
        movl    %edx, %eax
        sarl    $31, %eax
        sarl    $31, %edx
        ret

which contains a strange duplication of "sarl" instructions caused by
the i386 backend's ashrdi3 splitter generating this sequence too late
to be CSE'd.  The patch below special cases this operation to produce

foo:    movl    8(%esp), %edx
        sarl    $31, %edx
        movl    %edx, %eax
        ret

which if nothing else is shorter than the original.


Alas I'm ignorant of the scheduling/pipeling constraints and instruction
pairing on Pentium and Athlon class processors, so I can't be sure that
this patch is always an improvement.  Perhaps this hunk could be guarded
by optimize_size if there's a potential stall issue.


The following patch has been tested on i686-pc-linux-gnu, all languages
except Ada and treelang, and regression tested with a top-level "make -k
check" with no new failures.

Ok for mainline?



2004-03-11  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.c (ix86_split_ashrdi): Optimize shift by 63.


Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.657
diff -c -3 -p -r1.657 i386.c
*** i386.c	4 Mar 2004 20:11:04 -0000	1.657
--- i386.c	11 Mar 2004 21:50:49 -0000
*************** ix86_split_ashrdi (rtx *operands, rtx sc
*** 10873,10879 ****
        split_di (operands, 2, low, high);
        count = INTVAL (operands[2]) & 63;

!       if (count >= 32)
  	{
  	  emit_move_insn (low[0], high[1]);

--- 10873,10885 ----
        split_di (operands, 2, low, high);
        count = INTVAL (operands[2]) & 63;

!       if (count == 63)
! 	{
! 	  emit_move_insn (high[0], high[1]);
! 	  emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31)));
! 	  emit_move_insn (low[0], high[0]);
! 	}
!       else if (count >= 32)
  	{
  	  emit_move_insn (low[0], high[1]);


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]