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]

PR ice/13473


Hi,
the problem is that recog calls replacement of (reg X) by (subreg (reg X)).
This is sane because it first take care to change mode of (reg X).
validate_replace_rtx usually is able to deal with this, but in this case
it gets into recursive replacement because it sees already replaced RTL
throught sharing inside ASM_OPERANDS.

typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

#define CF (1<<0)
#define PF (1<<2)
#define AF (1<<4)
#define ZF (1<<6)
#define SF (1<<7)
#define OF (1<<11)

#define EFLAGS_BITS (CF|PF|AF|ZF|SF|OF)

void test16(uint16_t x, uint32_t eflags)
{
        uint16_t bsr_result;
        uint32_t bsr_eflags;
        uint16_t bsf_result;
        uint32_t bsf_eflags;

        __asm volatile(""
                : "=&r" (bsr_result), "=&r" (bsr_eflags)
                : "r" (x), "i" (~EFLAGS_BITS), "r" (eflags));
        __asm volatile(""
                : "=&r" (bsf_result), "=&r" (bsf_eflags)
                : "r" (x), "i" (~EFLAGS_BITS), "r" (eflags));
        printf("%08x %04x bsrw %02x %08x bsfw %02x %08x\n",
                x, eflags, bsr_result, bsr_eflags, bsf_result, bsf_eflags);
}

	PR ice/13473
	* recog.c (validate_replace_rtx_1):  Take care for RTL sharing inside
	ASM input operands
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.190
diff -c -3 -p -r1.190 recog.c
*** recog.c	11 Dec 2003 00:20:46 -0000	1.190
--- recog.c	29 Dec 2003 11:20:13 -0000
*************** validate_replace_rtx_1 (rtx *loc, rtx fr
*** 476,491 ****
        return;
      }
  
!   /* Call ourself recursively to perform the replacements.  */
  
!   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
!       if (fmt[i] == 'e')
! 	validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
!       else if (fmt[i] == 'E')
! 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
      }
  
    /* If we didn't substitute, there is nothing more to do.  */
    if (num_changes == prev_changes)
--- 476,513 ----
        return;
      }
  
!   /* Call ourself recursively to perform the replacements.
!      We must not replace inside already replaced expression, otherwise we
!      get infinite recursion for replacements like (reg X)->(subreg (reg X))
!      done by regmove, so we must special case shared ASM_OPERANDS.  */
  
!   if (GET_CODE (x) == PARALLEL)
      {
!       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
! 	{
! 	  if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
! 	      && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
! 	    {
! 	      /* Verify that operands are really shared.  */
! 	      if (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0))) !=
! 		  ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, j))))
! 		abort ();
! 	      validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
! 				      from, to, object);
! 	    }
! 	  else
! 	    validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object);
! 	}
      }
+   else
+     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+       {
+ 	if (fmt[i] == 'e')
+ 	  validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
+ 	else if (fmt[i] == 'E')
+ 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ 	    validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+       }
  
    /* If we didn't substitute, there is nothing more to do.  */
    if (num_changes == prev_changes)


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