Re: Avoiding paradoxical subregs

2014-01-18 Thread Paulo J. Matos

On 18/01/14 20:11, pins...@gmail.com wrote:




On Jan 18, 2014, at 12:04 PM, "Paulo J. Matos"  wrote:

On 17/01/14 17:36, Eric Botcazou wrote:

I am not implying that this is a GCC bug, unless you think
WORD_REISTER_OPERATIONS should have avoided the creation of such
paradoxical subreg.


No, that's precisely the contrary, WORD_REGISTER_OPERATIONS tends to create
paradoxical subregs.


I might then, be misunderstanding the reason to enable 
WORD_REGISTER_OPERATIONS. From the documentation:

"Macro: WORD_REGISTER_OPERATIONS

Define this macro if operations between registers with integral mode smaller 
than a word are always performed on the entire register. Most RISC machines have 
this property and most CISC machines do not. "

The machine I am targeting is a 64bit vector machine. When you perform a 16 bit 
operation, the whole register is changed because the operation actually changes 
every 16bit group of the register. So it seems I should enable 
WORD_REGISTER_OPERATIONS.

As an aside, is there any machine in gcc mainline like this?


Yes spu.  It is a 128bit vector machine, operations happen in that size and 
compares are done in the same size.



Thanks for the reference.


I think you misunderstood WORD_REGISTER_OPERATIONS, it means the operation 
happens on the whole register in that a 16bit add is the same as a 32bit one.



Oh... my... you're right. If I now read the doc for 
WORD_REGISTER_OPERATIONS what you're saying makes sense. I shouldn't 
have it enabled.


Thanks for your help.

Paulo Matos


Thanks,
Andrew Pinski




--
PMatos



Re: Avoiding paradoxical subregs

2014-01-18 Thread pinskia


> On Jan 18, 2014, at 12:04 PM, "Paulo J. Matos"  wrote:
> 
> On 17/01/14 17:36, Eric Botcazou wrote:
>>> I am not implying that this is a GCC bug, unless you think
>>> WORD_REISTER_OPERATIONS should have avoided the creation of such
>>> paradoxical subreg.
>> 
>> No, that's precisely the contrary, WORD_REGISTER_OPERATIONS tends to create
>> paradoxical subregs.
> 
> I might then, be misunderstanding the reason to enable 
> WORD_REGISTER_OPERATIONS. From the documentation:
> 
> "Macro: WORD_REGISTER_OPERATIONS
> 
>Define this macro if operations between registers with integral mode 
> smaller than a word are always performed on the entire register. Most RISC 
> machines have this property and most CISC machines do not. "
> 
> The machine I am targeting is a 64bit vector machine. When you perform a 16 
> bit operation, the whole register is changed because the operation actually 
> changes every 16bit group of the register. So it seems I should enable 
> WORD_REGISTER_OPERATIONS.
> 
> As an aside, is there any machine in gcc mainline like this?

Yes spu.  It is a 128bit vector machine, operations happen in that size and 
compares are done in the same size.

I think you misunderstood WORD_REGISTER_OPERATIONS, it means the operation 
happens on the whole register in that a 16bit add is the same as a 32bit one.

Thanks,
Andrew Pinski


> 
>>> What I was looking after was for a generic solution on
>>> my backend that either eliminates the use of paradoxical subregs or forces
>>> reload the transform (subreg:m (reg:n K)), where subreg is paradoxical,
>>> into a zero_extend.
>> 
>> Why would it do that?  That would pessimize for no clear benefit.  Either the
>> paradoxical subreg is correct and there is bug in reload or it is wrong and
>> there is a bug in combine.
> 
> When combine transforms:
> (zero_extend:SI (reg:HI 18))
> into
> (subreg:SI (reg:HI 18))
> it seems then to be doing something wrong. This is because the first 
> explicitly says that bits 0-15 have the value in reg 18 and the bits 16-31 
> are zero. However the second means that bits 0-15 have the value in reg 18 
> and the bits 16-31 may or may not be defined. These are not equivalent I 
> think. So, following your reasoning combine has a bug. Do you agree? If so, I 
> will look for where this transformation is combine is happening.
> 
> 
> -- 
> PMatos
> 


Re: Avoiding paradoxical subregs

2014-01-18 Thread Paulo J. Matos

On 17/01/14 17:36, Eric Botcazou wrote:

I am not implying that this is a GCC bug, unless you think
WORD_REGISTER_OPERATIONS should have avoided the creation of such
paradoxical subreg.


No, that's precisely the contrary, WORD_REGISTER_OPERATIONS tends to create
paradoxical subregs.



I might then, be misunderstanding the reason to enable 
WORD_REGISTER_OPERATIONS. From the documentation:


"Macro: WORD_REGISTER_OPERATIONS

Define this macro if operations between registers with integral 
mode smaller than a word are always performed on the entire register. 
Most RISC machines have this property and most CISC machines do not. "


The machine I am targeting is a 64bit vector machine. When you perform a 
16 bit operation, the whole register is changed because the operation 
actually changes every 16bit group of the register. So it seems I should 
enable WORD_REGISTER_OPERATIONS.


As an aside, is there any machine in gcc mainline like this?


What I was looking after was for a generic solution on
my backend that either eliminates the use of paradoxical subregs or forces
reload the transform (subreg:m (reg:n K)), where subreg is paradoxical,
into a zero_extend.


Why would it do that?  That would pessimize for no clear benefit.  Either the
paradoxical subreg is correct and there is bug in reload or it is wrong and
there is a bug in combine.



When combine transforms:
(zero_extend:SI (reg:HI 18))
into
(subreg:SI (reg:HI 18))
it seems then to be doing something wrong. This is because the first 
explicitly says that bits 0-15 have the value in reg 18 and the bits 
16-31 are zero. However the second means that bits 0-15 have the value 
in reg 18 and the bits 16-31 may or may not be defined. These are not 
equivalent I think. So, following your reasoning combine has a bug. Do 
you agree? If so, I will look for where this transformation is combine 
is happening.



--
PMatos



Re: Avoiding paradoxical subregs

2014-01-17 Thread Eric Botcazou
> I am not implying that this is a GCC bug, unless you think
> WORD_REGISTER_OPERATIONS should have avoided the creation of such
> paradoxical subreg.

No, that's precisely the contrary, WORD_REGISTER_OPERATIONS tends to create 
paradoxical subregs.

> What I was looking after was for a generic solution on
> my backend that either eliminates the use of paradoxical subregs or forces
> reload the transform (subreg:m (reg:n K)), where subreg is paradoxical,
> into a zero_extend.

Why would it do that?  That would pessimize for no clear benefit.  Either the 
paradoxical subreg is correct and there is bug in reload or it is wrong and 
there is a bug in combine.

-- 
Eric Botcazou


RE: Avoiding paradoxical subregs

2014-01-17 Thread Paulo Matos
> -Original Message-
> From: Eric Botcazou [mailto:ebotca...@adacore.com]
> Sent: 17 January 2014 16:23
> To: Paulo Matos
> Cc: gcc@gcc.gnu.org
> Subject: Re: Avoiding paradoxical subregs
> 
> > I can use canonicalize_comparison like s390 to remove the subreg, however
> > the question then becomes about how to avoid this in general. We cannot
> > allow a zero_extend to become a paradoxical subreg and then have the subreg
> > discarded. Most of our instructions are vector instructions which will
> > change the remainder of the register.
> >
> > I have defined WORD_REGISTER_OPERATIONS and CANNOT_CHANGE_MODE_CLASS(from,
> > to, class) and set it to true if GET_MODE_SIZE (from) < GET_MODE_SIZE (to)
> > but it didn't help.
> >
> > Any suggestions for a generic solution?
> 
> What kind of generic solution?  Eliminating paradoxical subregs altogether?
> That's very likely not doable if you define WORD_REGISTER_OPERATIONS anyway.
> You need to pinpoint where things start to go wrong, for example in combine.
> 

I am not implying that this is a GCC bug, unless you think 
WORD_REGISTER_OPERATIONS should have avoided the creation of such paradoxical 
subreg. What I was looking after was for a generic solution on my backend that 
either eliminates the use of paradoxical subregs or forces reload the transform 
(subreg:m (reg:n K)), where subreg is paradoxical, into a zero_extend.

I mentioned a generic one because the only solution I have is for comparison 
instructions only:
canonicalize_comparison (int *, rtx *op0, rtx *,
  bool op0_preserve_value)
{
  if (op0_preserve_value)
return;

  /* Remove paradoxical subregs.  */
  if (GET_CODE (*op0) == SUBREG)
{
  rtx inner = SUBREG_REG (*op0);

  if (GET_MODE_SIZE (GET_MODE (inner)) < GET_MODE_SIZE (GET_MODE (*op0)))
*op0 = simplify_gen_unary (ZERO_EXTEND, GET_MODE (*op0), inner, 
GET_MODE (inner));
}
}

Another more generic solution would be to write my own register_operand 
predicate that excludes paradoxical subregs but I am not sure what kind of 
pandora's box I am opening by doing that.
-- 
Paulo Matos


Re: Avoiding paradoxical subregs

2014-01-17 Thread Eric Botcazou
> I can use canonicalize_comparison like s390 to remove the subreg, however
> the question then becomes about how to avoid this in general. We cannot
> allow a zero_extend to become a paradoxical subreg and then have the subreg
> discarded. Most of our instructions are vector instructions which will
> change the remainder of the register.
>
> I have defined WORD_REGISTER_OPERATIONS and CANNOT_CHANGE_MODE_CLASS(from,
> to, class) and set it to true if GET_MODE_SIZE (from) < GET_MODE_SIZE (to)
> but it didn't help.
>
> Any suggestions for a generic solution?

What kind of generic solution?  Eliminating paradoxical subregs altogether?  
That's very likely not doable if you define WORD_REGISTER_OPERATIONS anyway.
You need to pinpoint where things start to go wrong, for example in combine.

-- 
Eric Botcazou


Avoiding paradoxical subregs

2014-01-17 Thread Paulo Matos
Hello,

I am seeing GCC combining:
(insn 17 16 18 3 (set (reg:SI 104 [ D.4588 ])
(zero_extend:SI (reg:HI 103 [ D.4587 ]))) test-18.c:24 1426 
{zero_extendhisi2}
 (expr_list:REG_DEAD (reg:HI 103 [ D.4587 ])
(nil)))
(insn 18 17 19 3 (set (reg:BI 105)
(gt:BI (reg:SI 104 [ D.4588 ])
(const_int 4 [0x4]))) test-18.c:24 1372 {cmp_simode}
 (expr_list:REG_DEAD (reg:SI 104 [ D.4588 ])
(nil)))

into a paradoxical use:
(set (reg:BI 105)
(gt:BI (subreg:SI (reg:HI 103 [ D.4587 ]) 0)
(const_int 4 [0x4])))


Reload then transforms (subreg:SI (reg:HI 103 [ D.4587 ]) 0) into (reg:SI 18), 
allocating 103 to 18, but changing the mode to SI.
This is wrong and it will generate wrong code.

I can use canonicalize_comparison like s390 to remove the subreg, however the 
question then becomes about how to avoid this in general. We cannot allow a 
zero_extend to become a paradoxical subreg and then have the subreg discarded. 
Most of our instructions are vector instructions which will change the 
remainder of the register.

I have defined WORD_REGISTER_OPERATIONS and CANNOT_CHANGE_MODE_CLASS(from, to, 
class) and set it to true if GET_MODE_SIZE (from) < GET_MODE_SIZE (to) but it 
didn't help.

Any suggestions for a generic solution?

Paulo Matos