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]

Re: [PATCH] Simplify a VEC_SELECT fed by its own inverse


Hi Marc,

Good points!  I will rework the patch with your suggestions in mind.

Thanks!
Bill

On Mon, 2014-04-21 at 18:51 +0200, Marc Glisse wrote:
> On Mon, 21 Apr 2014, Bill Schmidt wrote:
> 
> > Note that it would be possible to do a more general transformation here,
> > in which any vec_select feeding another could be replaced by a
> > vec_select performing the composite function of the other two.  I have
> > not done this because I am unaware of this situation arising in
> > practice.  If it's desirable, I can extend the patch in this direction.
> 
> It does arise, but I think it isn't done because not all permutations are 
> (optimally) supported by all targets.
> 
> > Index: gcc/simplify-rtx.c
> > ===================================================================
> > --- gcc/simplify-rtx.c	(revision 209516)
> > +++ gcc/simplify-rtx.c	(working copy)
> > @@ -3673,6 +3673,34 @@ simplify_binary_operation_1 (enum rtx_code code, e
> > 	    }
> > 	}
> >
> > +      /* If we have two nested selects that are inverses of each
> > +	 other, replace them with the source operand.  */
> > +      if (GET_CODE (trueop0) == VEC_SELECT)
> > +	{
> > +	  enum machine_mode reg_mode = GET_MODE (XEXP (trueop0, 0));
> > +	  rtx op0_subop1 = XEXP (trueop0, 1);
> > +	  gcc_assert (VECTOR_MODE_P (reg_mode));
> > +	  gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER (reg_mode));
> > +	  gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
> > +
> > +	  if (XVECLEN (trueop1, 0) == XVECLEN (op0_subop1, 0))
> > +	    {
> > +	      /* Apply the second ordering vector to the first.
> > +		 If the result is { 0, 1, ..., n-1 } then the
> > +		 two VEC_SELECTs cancel.  */
> > +	      for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
> > +		{
> > +		  rtx x = XVECEXP (trueop1, 0, i);
> > +		  gcc_assert (CONST_INT_P (x));
> > +		  rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
> > +		  gcc_assert (CONST_INT_P (y));
> > +		  if (i != INTVAL (y))
> > +		    return 0;
> > +		}
> > +	      return XEXP (trueop0, 0);
> > +	    }
> > +	}
> 
> I may have missed it, but don't you want to check that what you are 
> returning has the right mode/length (or generate the obvious vec_select 
> otherwise)? I don't know if any platform has such constructions (probably 
> not), but in principle you could start from a vector of size 4, extract 
> {1,0} from it, extract {1,0} from that, and you don't want to return the 
> initial vector as is. On the other hand, I don't think you really care 
> whether trueop1 is smaller than op0_subop1. Starting from a vector of size 
> 2, extracting {1,0,1,0} then {3,0} gives the initial vector just fine.
> 


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