[patch] m68k/*.md: Fix PR target/24949. (Take 2)

Kazu Hirata kazu@codesourcery.com
Mon Nov 28 00:26:00 GMT 2005


Hi,

Attached is a patch to fix PR target/24949.

The current GCC triggers an ICE while compiling
gcc.c-torture/compile/20000403-2.c

20000403-2.c: In function 'foo':
20000403-2.c:5: error: unrecognizable insn:
(insn 8 6 9 1
      (set (mem/c/i:DI (reg/f:SI 25 virtual-incoming-args) [0 tmp+0 S8 A32])
	   (ashiftrt:DI (mem/c/i:DI (reg/f:SI 25 virtual-incoming-args) [0 tmp+0 S8 A32])
			(const_int 32 [0x20]))) -1 (nil)
			(nil))

This is because expander "ashrdi3" accepts shift count of 32, but
there is no corresponding shift insn that accepts memory source and
memory destination.  There is an insn that accepts such operands *if*
it comes with a scratch register though.

The patch solves this problem by attaching a scratch register for
every ashiftrt:DI case and merging two ashiftrt:DI patterns with shift
count being 32.  Of course, if a scratch register is not needed, it
will not be allocated.  Look for use of 'X' as a constraint.

Andreas suggested that ashift:DI might have the same problem.  It
turns out that ashift:DI does not require a scratch register, so the
story above is not applicable.

Tested on m68k-none-elf.  OK to apply?

Kazu Hirata

2005-11-27  Kazu Hirata  <kazu@codesourcery.com>

	* config/m68k/m68k.md (ashrdi_const32_mem, ashrdi3): Use
	ashrdi_const_operand.

Index: config/m68k/m68k.md
===================================================================
*** config/m68k/m68k.md	(revision 107575)
--- config/m68k/m68k.md	(working copy)
***************
*** 4069,4110 ****
  })
  
  (define_insn "ashrdi_const32"
!   [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
! 		     (const_int 32)))]
!   ""
! {
!   CC_STATUS_INIT;
!   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!   if (TARGET_68020)
!     return "move%.l %1,%2\;smi %0\;extb%.l %0";
!   else
!     return "move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0";
! })
! 
! (define_insn "ashrdi_const32_mem"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=o,<")
! 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro")
  		     (const_int 32)))
!    (clobber (match_scratch:SI 2 "=d,d"))]
    ""
  {
    CC_STATUS_INIT;
!   if (which_alternative == 1)
!     operands[3] = operands[0];
!   else
!     operands[3] = adjust_address (operands[0], SImode, 4);
!   if (TARGET_68020)
!     return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
    else
!     return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
  })
  
  ;; The predicate below must be general_operand, because ashrdi3 allows that
  (define_insn "ashrdi_const"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
  	(ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
! 		     (match_operand 2 "const_int_operand" "n")))]
    "(!TARGET_COLDFIRE 
      && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
  	|| INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
--- 4069,4108 ----
  })
  
  (define_insn "ashrdi_const32"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o,<")
! 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
  		     (const_int 32)))
!    (clobber (match_scratch:SI 2 "=X,d,d"))]
    ""
  {
    CC_STATUS_INIT;
!   if (which_alternative == 0)
!     {
!       operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!       if (TARGET_68020)
! 	return "move%.l %1,%2\;smi %0\;extb%.l %0";
!       else
! 	return "move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0";
!     }
    else
!     {
!       if (which_alternative == 2)
! 	operands[3] = operands[0];
!       else if (which_alternative == 1)
! 	operands[3] = adjust_address (operands[0], SImode, 4);
!       if (TARGET_68020)
! 	return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
!       else
! 	return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
!     }
  })
  
  ;; The predicate below must be general_operand, because ashrdi3 allows that
  (define_insn "ashrdi_const"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
  	(ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
! 		     (match_operand 2 "const_int_operand" "n")))
!    (clobber (match_scratch:SI 3 "=X"))]
    "(!TARGET_COLDFIRE 
      && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
  	|| INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
***************
*** 4141,4149 ****
  })
  
  (define_expand "ashrdi3"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "")
! 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "")
! 		     (match_operand 2 "const_int_operand" "")))]
    "!TARGET_COLDFIRE"
    "
  {
--- 4139,4148 ----
  })
  
  (define_expand "ashrdi3"
!   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
! 		   (ashiftrt:DI (match_operand:DI 1 "general_operand" "")
! 				(match_operand 2 "const_int_operand" "")))
! 	      (clobber (match_scratch:SI 3 ""))])]
    "!TARGET_COLDFIRE"
    "
  {
***************
*** 4154,4159 ****
--- 4153,4159 ----
  	  && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
  	  && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
      FAIL;
+   operands[3] = gen_rtx_SCRATCH (SImode);
  } ")
  
  ;; On all 68k models, this makes faster code in a special case.



More information about the Gcc-patches mailing list