why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Konstantin Vladimirov
Hi,

Consider code:

char A;
char B;

char sum_A_B ( void )
{
  char sum = A + B;

  return sum;
}


Compile it on any backend (for example x86):
gcc (SUSE Linux) 4.5.0 20100604 [gcc-4_5-branch revision 160292]

gcc -m32 -O2 -S repro.c -fdump-tree-all-lineno-details

Now look at repro.c.004t.gimple:

sum_A_B ()
[repro.c : 5:1] {
  char A.0;
  unsigned char A.1;
  char B.2;
  unsigned char B.3;
  unsigned char D.1990;
  char D.1991;
  char sum;

  [repro.c : 6:8] A.0 = A;
  [repro.c : 6:8] A.1 = (unsigned char) A.0;
  [repro.c : 6:8] B.2 = B;
  [repro.c : 6:8] B.3 = (unsigned char) B.2;
  [repro.c : 6:8] D.1990 = A.1 + B.3;
  [repro.c : 6:8] sum = (char) D.1990;
  [repro.c : 8:3] D.1991 = sum;
  [repro.c : 8:3] return D.1991;
}

It looks really weird. Why gcc promotes char to unsigned char internally?

This case is simple repro, but in my production code it is a reason of
productivity overhead (vectorizer fails on such promotions).

Thanks in advance for any responses. Previous discussion about inline
assembler was really helpful.

---
With best regards, Konstantin


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Miles Bader
Konstantin Vladimirov  writes:
> It looks really weird. Why gcc promotes char to unsigned char internally?

Hmm, maybe not useful, but if you used "unsigned char" as the variable
types or the -funsigned-char command-line option, it won't ('cause the
variables will already be unsigned)...

-miles

-- 
Politics, n. A strife of interests masquerading as a contest of
principles. The conduct of public affairs for private advantage.


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Jakub Jelinek
On Thu, Jan 26, 2012 at 02:27:45PM +0400, Konstantin Vladimirov wrote:
> Consider code:
> 
> char A;
> char B;
> 
> char sum_A_B ( void )
> {
>   char sum = A + B;
> 
>   return sum;
> }
>   [repro.c : 6:8] A.0 = A;
>   [repro.c : 6:8] A.1 = (unsigned char) A.0;
>   [repro.c : 6:8] B.2 = B;
>   [repro.c : 6:8] B.3 = (unsigned char) B.2;
>   [repro.c : 6:8] D.1990 = A.1 + B.3;
>   [repro.c : 6:8] sum = (char) D.1990;
>   [repro.c : 8:3] D.1991 = sum;
>   [repro.c : 8:3] return D.1991;
> }
> 
> It looks really weird. Why gcc promotes char to unsigned char internally?

To avoid triggering undefined behavior.
A + B in C for char A and B is (int) A + (int) B, so either we'd have to
promote it to int and then demote, or we just cast it to unsigned and do the
addition in 8-bit.  If we don't do that, e.g. for
A = 127 and B = 127 we'd trigger undefined behavior of signed addition.
In unsigned char 127 + 127 is valid.

Jakub


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Konstantin Vladimirov
Hi,

If I know what I am doing, and my code itself guarantees, that there
will be no overflows and UB here, can I switch off this signed char to
unsigned char expansion in favor of signed char to signed int
expansion?

---
With best regards, Konstantin

On Thu, Jan 26, 2012 at 3:04 PM, Jakub Jelinek  wrote:
> On Thu, Jan 26, 2012 at 02:27:45PM +0400, Konstantin Vladimirov wrote:
>> Consider code:
>>
>> char A;
>> char B;
>>
>> char sum_A_B ( void )
>> {
>>   char sum = A + B;
>>
>>   return sum;
>> }
>>   [repro.c : 6:8] A.0 = A;
>>   [repro.c : 6:8] A.1 = (unsigned char) A.0;
>>   [repro.c : 6:8] B.2 = B;
>>   [repro.c : 6:8] B.3 = (unsigned char) B.2;
>>   [repro.c : 6:8] D.1990 = A.1 + B.3;
>>   [repro.c : 6:8] sum = (char) D.1990;
>>   [repro.c : 8:3] D.1991 = sum;
>>   [repro.c : 8:3] return D.1991;
>> }
>>
>> It looks really weird. Why gcc promotes char to unsigned char internally?
>
> To avoid triggering undefined behavior.
> A + B in C for char A and B is (int) A + (int) B, so either we'd have to
> promote it to int and then demote, or we just cast it to unsigned and do the
> addition in 8-bit.  If we don't do that, e.g. for
> A = 127 and B = 127 we'd trigger undefined behavior of signed addition.
> In unsigned char 127 + 127 is valid.
>
>        Jakub


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Richard Guenther
On Thu, Jan 26, 2012 at 12:53 PM, Konstantin Vladimirov
 wrote:
> Hi,
>
> If I know what I am doing, and my code itself guarantees, that there
> will be no overflows and UB here, can I switch off this signed char to
> unsigned char expansion in favor of signed char to signed int
> expansion?

No, you can't.

Richard.

> ---
> With best regards, Konstantin
>
> On Thu, Jan 26, 2012 at 3:04 PM, Jakub Jelinek  wrote:
>> On Thu, Jan 26, 2012 at 02:27:45PM +0400, Konstantin Vladimirov wrote:
>>> Consider code:
>>>
>>> char A;
>>> char B;
>>>
>>> char sum_A_B ( void )
>>> {
>>>   char sum = A + B;
>>>
>>>   return sum;
>>> }
>>>   [repro.c : 6:8] A.0 = A;
>>>   [repro.c : 6:8] A.1 = (unsigned char) A.0;
>>>   [repro.c : 6:8] B.2 = B;
>>>   [repro.c : 6:8] B.3 = (unsigned char) B.2;
>>>   [repro.c : 6:8] D.1990 = A.1 + B.3;
>>>   [repro.c : 6:8] sum = (char) D.1990;
>>>   [repro.c : 8:3] D.1991 = sum;
>>>   [repro.c : 8:3] return D.1991;
>>> }
>>>
>>> It looks really weird. Why gcc promotes char to unsigned char internally?
>>
>> To avoid triggering undefined behavior.
>> A + B in C for char A and B is (int) A + (int) B, so either we'd have to
>> promote it to int and then demote, or we just cast it to unsigned and do the
>> addition in 8-bit.  If we don't do that, e.g. for
>> A = 127 and B = 127 we'd trigger undefined behavior of signed addition.
>> In unsigned char 127 + 127 is valid.
>>
>>        Jakub


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread Jakub Jelinek
On Thu, Jan 26, 2012 at 03:53:59PM +0400, Konstantin Vladimirov wrote:
> If I know what I am doing, and my code itself guarantees, that there
> will be no overflows and UB here, can I switch off this signed char to
> unsigned char expansion in favor of signed char to signed int
> expansion?

Obviously promotion to signed int, doing addition there and demoting
back to char would create much worse code when vectorized.
The primary problem is that your GCC is too old, retry with 4.6+.
In particular you are interested in http://gcc.gnu.org/PR44284 .
Current GCC vectorizes it just fine.

Jakub


-mavx option

2012-01-26 Thread Ulrich Drepper
I think gcc is missing an option since -mavx controls two different
things.  First, the generation of VEX-encoded instructions.  Second,
the use of ymm registers.  The latter is not always available when the
former is and using VEX-encoded instructions by themselves can have an
advantage.  Currently, when OSXAVE is not available (use xgetbv to
test etc etc) then I cannot use code which gcc generates with -mavx
even though I am only interested in the VEX encoding.

Could we have a -mvex option which is automatically implied in -mavx?


Re: fixed_scalar_and_varying_struct_p and varies_p

2012-01-26 Thread Richard Guenther
On Wed, Jan 25, 2012 at 8:20 PM, Richard Sandiford
 wrote:
> Richard Guenther  writes:
>> I'd say open a missed optimization bug with the testcase and go ahead
>> with both patches.
>
> OK, I committed the patches yesterday and I've just opened PR 52000
> for the missed optimisation.

Btw, looking at the m32c code what it does is valid regardless of
MEM_SCALAR_P or MEM_IN_STRUCT_P - I don't see why they should
be relevant.  But it needs to cater for MEM_OFFSET and MEM_ALIAS_SET
at least

> Richard


Re: why GCC does implicit promotion to unsigned char?

2012-01-26 Thread David Brown

On 26/01/2012 12:53, Konstantin Vladimirov wrote:

Hi,

If I know what I am doing, and my code itself guarantees, that there
will be no overflows and UB here, can I switch off this signed char to
unsigned char expansion in favor of signed char to signed int
expansion?



The big question here is why you are using an unqualified "char" for 
arithmetic in the first place.  The signedness of plain "char" varies by 
target (some default to signed, some to unsigned) and by compiler flags. 
 If you want to write code that uses signed chars, use "signed char". 
Or even better, use  type "int8_t".


However, as has been pointed out, the problem is that signed arithmetic 
doesn't wrap - it must be turned into unsigned arithmetic to make it 
safe.  An alternative is to tell gcc that signed arithmetic is 2's 
compliment and wraps, by using the "-fwrapv" flag or "int8_t char 
sum_A_B(void) __attribute__((optimize("wrapv")));" on the specific function.


mvh.,

David



---
With best regards, Konstantin

On Thu, Jan 26, 2012 at 3:04 PM, Jakub Jelinek  wrote:

On Thu, Jan 26, 2012 at 02:27:45PM +0400, Konstantin Vladimirov wrote:

Consider code:

char A;
char B;

char sum_A_B ( void )
{
   char sum = A + B;

   return sum;
}
   [repro.c : 6:8] A.0 = A;
   [repro.c : 6:8] A.1 = (unsigned char) A.0;
   [repro.c : 6:8] B.2 = B;
   [repro.c : 6:8] B.3 = (unsigned char) B.2;
   [repro.c : 6:8] D.1990 = A.1 + B.3;
   [repro.c : 6:8] sum = (char) D.1990;
   [repro.c : 8:3] D.1991 = sum;
   [repro.c : 8:3] return D.1991;
}

It looks really weird. Why gcc promotes char to unsigned char internally?


To avoid triggering undefined behavior.
A + B in C for char A and B is (int) A + (int) B, so either we'd have to
promote it to int and then demote, or we just cast it to unsigned and do the
addition in 8-bit.  If we don't do that, e.g. for
A = 127 and B = 127 we'd trigger undefined behavior of signed addition.
In unsigned char 127 + 127 is valid.

Jakub






Re: -mavx option

2012-01-26 Thread Paweł Sikora
On Thursday 26 of January 2012 09:52:22 Ulrich Drepper wrote:
> I think gcc is missing an option since -mavx controls two different
> things.  First, the generation of VEX-encoded instructions.  Second,
> the use of ymm registers.  The latter is not always available when the
> former is and using VEX-encoded instructions by themselves can have an
> advantage.  Currently, when OSXAVE is not available (use xgetbv to
> test etc etc) then I cannot use code which gcc generates with -mavx
> even though I am only interested in the VEX encoding.
> 
> Could we have a -mvex option which is automatically implied in -mavx?

there's a -msse2avx option. is it enough?



gcc-4.5-20120126 is now available

2012-01-26 Thread gccadmin
Snapshot gcc-4.5-20120126 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/4.5-20120126/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 4.5 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch 
revision 183585

You'll find:

 gcc-4.5-20120126.tar.bz2 Complete GCC

  MD5=a3e3762590c6514f02cfa01f4876995e
  SHA1=636513d3ab7d2dda56386a9e63a53327ed5bc72c

Diffs from 4.5-20120119 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-4.5
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.