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]

[patch] combine_simplify_rtx clobbers shared rtl


In one of the internal ports I'm working with, we are
mis-compiling gcc.c-torture/960317-1.c.  The problem occurs when
combine is called with:

-----------------------------------------------------------------------------
i1: (insn 12 11 15 (set (reg/v:SI 51)
        (ashift:SI (const_int -1 [0xffffffff])
            (reg/v:SI 49))) 31 {*ashlsi3_internal} (insn_list 4 (nil))
    (expr_list:REG_DEAD (reg/v:SI 49)
        (nil)))


i2: (insn 17 15 18 (set (reg:SI 53)
        (const_int 0 [0x0])) 4 {*movsi_internal} (nil)
    (expr_list:REG_EQUAL (const_int 0 [0x0])
        (nil)))


i3: (insn 18 17 21 (set (reg:SI 53)
        (neg:SI (reg/v:SI 51))) 9 {*subsi3_internal} (insn_list 12 (insn_list 17 (nil)))
    (nil))
-----------------------------------------------------------------------------

This is the sequence of events that leads to the problem:

1- In try_combine(), we call subst() to substitute (reg/v:SI 51)
   with (ashift:SI (const_int -1) (reg/v:SI 49)).

2- subst() will make the substitution resulting in the new
   pattern 'x':

   (neg:SI (ashift:SI (const_int -1 [0xffffffff])
           (reg/v:SI 49)))

3- Now subst() calls combine_simplify_rtx() with 'x'.  Since this
   is the negation of a shift, we can replace '-(-1<<r49)' with
   '1<<r49'.  However, in doing so, instead of generating new RTL
   for the shift, we re-write the original shift expression.

   Since subst() had decided not to deep-copy the shift
   expression, we end up modifying the original shift expression
   in i1.  This is wrong.


This patch modifies combine_simplify_rtx() to create new RTL when
simplifying (neg (ashift () ())) expressions.  Bootstrapped and
regression tested on i686-pc-linux-gnu.


Diego.


	* combine.c (combine_simplify_rtx): Generate a new shift operation
	when simplifying the first operand of a (neg (ashift)) expression.

Index: combine.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/combine.c,v
retrieving revision 1.259
diff -d -p -d -c -p -r1.259 combine.c
*** combine.c	2001/07/07 03:12:30	1.259
--- combine.c	2001/07/19 22:28:28
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3921,3930 ****
  	  temp = simplify_unary_operation (NEG, mode,
  					   XEXP (XEXP (x, 0), 0), mode);
  	  if (temp)
! 	    {
! 	      SUBST (XEXP (XEXP (x, 0), 0), temp);
! 	      return XEXP (x, 0);
! 	    }
  	}
  
        temp = expand_compound_operation (XEXP (x, 0));
--- 3921,3927 ----
  	  temp = simplify_unary_operation (NEG, mode,
  					   XEXP (XEXP (x, 0), 0), mode);
  	  if (temp)
! 	    return gen_binary (ASHIFT, mode, temp, XEXP (XEXP (x, 0), 1));
  	}
  
        temp = expand_compound_operation (XEXP (x, 0));


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