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 to SHmedia divide patterns


For TARGET_SHMEDIA_FPU, the udivsi3 pattern generates the
following sequence:

   (set (match_dup 3)
	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
   (set (match_dup 4)
	(zero_extend:DI (match_operand:SI 2 "register_operand" "")))
   (set (match_dup 5) (float:DF (match_dup 3)))
   (set (match_dup 6) (float:DF (match_dup 4)))
   (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
   (set (match_dup 8) (fix:DI (match_dup 7)))
   (set (match_operand:SI 0 "register_operand" "")
	(truncate:SI (match_dup 8)))

and then puts the whole thing in a REG_LIBCALL/REG_RETVAL block.
In the test case below, the result of one such block was constant
folded and so the block was removed.  Unfortunately, gcse had
reused the result of a conversion in a later instruction.

So, question is: is gcse wrong to reuse a value from inside a libcall
block, or shouldn't the backend have created one in the first place?

Looking though the ports, I think sh is the only one that wraps
pseudo operations in libcall block, so I assume it's the backend
that needs to change.

Patch tested on sh64-elf, fixes the attached test case.
OK to install?

Richard


	* config/sh/sh.md (udivsi3): Don't put udivsi3_i4_media instructions
	into a libcall block.
	(divsi3): Likewise divsi3_i4_media.

Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.125
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.125 sh.md
*** config/sh/sh.md	31 Oct 2002 12:53:06 -0000	1.125
--- config/sh/sh.md	14 Nov 2002 17:11:14 -0000
*************** (define_expand "udivsi3"
*** 1341,1347 ****
    ""
    "
  {
!   rtx first = 0, last;
  
    operands[3] = gen_reg_rtx (Pmode);
    /* Emit the move of the address to a pseudo outside of the libcall.  */
--- 1341,1347 ----
    ""
    "
  {
!   rtx first, last;
  
    operands[3] = gen_reg_rtx (Pmode);
    /* Emit the move of the address to a pseudo outside of the libcall.  */
*************** (define_expand "udivsi3"
*** 1358,1365 ****
      {
        operands[1] = force_reg (SImode, operands[1]);
        operands[2] = force_reg (SImode, operands[2]);
!       last = gen_udivsi3_i4_media (operands[0], operands[1], operands[2]);
!       first = last;
      }
    else if (TARGET_SH5)
      {
--- 1358,1365 ----
      {
        operands[1] = force_reg (SImode, operands[1]);
        operands[2] = force_reg (SImode, operands[2]);
!       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
!       DONE;
      }
    else if (TARGET_SH5)
      {
*************** (define_expand "udivsi3"
*** 1386,1396 ****
  		      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
        last = gen_udivsi3_i1 (operands[0], operands[3]);
      }
!   if (! first)
!     {
!       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
!       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
!     }
    last = emit_insn (last);
    /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
       invariant code motion can move it.  */
--- 1386,1393 ----
  		      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
        last = gen_udivsi3_i1 (operands[0], operands[3]);
      }
!   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
!   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
    last = emit_insn (last);
    /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
       invariant code motion can move it.  */
*************** (define_expand "divsi3"
*** 1494,1500 ****
    ""
    "
  {
!   rtx first = 0, last;
  
    operands[3] = gen_reg_rtx (Pmode);
    /* Emit the move of the address to a pseudo outside of the libcall.  */
--- 1491,1497 ----
    ""
    "
  {
!   rtx first, last;
  
    operands[3] = gen_reg_rtx (Pmode);
    /* Emit the move of the address to a pseudo outside of the libcall.  */
*************** (define_expand "divsi3"
*** 1511,1518 ****
      {
        operands[1] = force_reg (SImode, operands[1]);
        operands[2] = force_reg (SImode, operands[2]);
!       last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
!       first = last;
      }
    else if (TARGET_SH5)
      {
--- 1508,1515 ----
      {
        operands[1] = force_reg (SImode, operands[1]);
        operands[2] = force_reg (SImode, operands[2]);
!       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
!       DONE;
      }
    else if (TARGET_SH5)
      {
*************** (define_expand "divsi3"
*** 1538,1548 ****
        emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
        last = gen_divsi3_i1 (operands[0], operands[3]);
      }
!   if (! first)
!     {
!       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
!       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
!     }
    last = emit_insn (last);
    /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
       invariant code motion can move it.  */
--- 1535,1542 ----
        emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
        last = gen_divsi3_i1 (operands[0], operands[3]);
      }
!   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
!   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
    last = emit_insn (last);
    /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
       invariant code motion can move it.  */
*** /dev/null	Tue Nov 14 21:44:43 2000
--- testsuite/gcc.c-torture/execute/20021112-4.c	Thu Nov 14 17:11:08 2002
***************
*** 0 ****
--- 1,21 ----
+ int g1, g2;
+ 
+ void foo (int x)
+ {
+   int y;
+ 
+   if (x)
+     y = 793;
+   else
+     y = 793;
+   g1 = 7930 / y;
+   g2 = 7930 / x;
+ }
+ 
+ int main ()
+ {
+   foo (793);
+   if (g1 != 10 || g2 != 10)
+     abort ();
+   exit (0);
+ }


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