Re: Option to make unsigned->signed conversion always well-defined?

2011-10-05 Thread Pedro Pedruzzi
Em 05-10-2011 17:11, Ulf Magnusson escreveu:
> Hi,
> 
> I've been experimenting with different methods for emulating the
> signed overflow of an 8-bit CPU.

You would like to check whether a 8-bit signed addition will overflow or
not, given the two operands. Is that correct?

As you used the word `emulating', I am assuming that your function will
not run by the mentioned CPU.

Does this 8-bit CPU use two's complement representation?

> The method I've found that seems to
> generate the most efficient code on both ARM and x86 is
> 
> bool overflow(unsigned int a, unsigned int b) {
> const unsigned int sum = (int8_t)a + (int8_t)b;
> return (int8_t)sum != sum;
> }
> 
> (The real function would probably be 'inline', of course. Regs are
> stored in overlong variables, hence 'unsigned int'.)
> 
> Looking at the spec, it unfortunately seems the behavior of this
> function is undefined, as it relies on signed int addition wrapping,
> and that (int8_t)sum truncates bits. Is there some way to make this
> guaranteed safe with GCC without resorting to inline asm? Locally
> enabling -fwrap takes care of the addition, but that still leaves the
> conversion.

I believe the cast from unsigned int to int8_t is implementation-defined
for values that can't be represented in int8_t (e.g. 0xff). A kind of
`undefined behavior' as well.

I tried:

bool overflow(unsigned int a, unsigned int b) {
const unsigned int sum = a + b;
    return ((a & 0x80) == (b & 0x80)) && ((a & 0x80) != (sum & 0x80));
}

But it is not as efficient as yours.

-- 
Pedro Pedruzzi


Re: Option to make unsigned->signed conversion always well-defined?

2011-10-06 Thread Pedro Pedruzzi
On Thu, Oct 6, 2011 at 11:04 AM, Miles Bader  wrote:
> How about:
>
>   bool overflowbit2(unsigned int a, unsigned int b)
>   {
>   const unsigned int sum = a + b;
>   return ~(a ^ b) & sum & 0x80;
>   }
>
> ?
>
> I thik it has the same results as your function...
> [I just made a table of all 8 possibilities, and checked!]

Miles, it is not the same. Take for example (0xff, 0xff). In 8-bit 2's
complement, this is (-1, -1) and does not overflow. Your function says
it does.


Em 06-10-2011 12:23, Jeremy Hall escreveu:
> bool overflow(int16_t a, int16_t b)
> {
>const int16_t sum = a + b;
>return sum > INT8_MAX || sum < INT8_MIN;
> }

Jeremy, here you are ignoring the problem of converting from the
unsigned int (in the range 0 to 0xff) to the signed integer that it
represents in 8-bit two's complement. Example: 0xff -> -1.

In practice, casting the unsigned int to int8_t works in most cases, but
it is compiler-defined. We are trying to find a always well-defined
approach that is efficient as well.


> Ops, should have been
> 
> return ~(a ^ b) & (a ^ sum) & 0x80
> 
> ~(a ^ b) gives 1 in the sign bit position if the signs are the same,
> and (a ^ sum) gives 1 if it's different in the sum.

This is good. Do you think this is suboptimal? How are you evaluating
efficiency? In x86 this generates pretty small code.

:
  400524:   8d 04 3elea(%rsi,%rdi,1),%eax
  400527:   31 f8   xor%edi,%eax
  400529:   31 f7   xor%esi,%edi
  40052b:   f7 d7   not%edi
  40052d:   21 f8   and%edi,%eax
  40052f:   25 80 00 00 00  and$0x80,%eax
  400534:   c3  retq

-- 
Pedro Pedruzzi



Re: Option to make unsigned->signed conversion always well-defined?

2011-10-07 Thread Pedro Pedruzzi
Em 07-10-2011 02:35, Miles Bader escreveu:
> Pedro Pedruzzi  writes:
>> On Thu, Oct 6, 2011 at 11:04 AM, Miles Bader  wrote:
>>> How about:
>>>
>>>   bool overflowbit2(unsigned int a, unsigned int b)
>>>   {
>>>   const unsigned int sum = a + b;
>>>   return ~(a ^ b) & sum & 0x80;
>>>   }
>>
>> Miles, it is not the same. Take for example (0xff, 0xff). In 8-bit
>> 2's complement, this is (-1, -1) and does not overflow. Your
>> function says it does.
> 
> Negative overflow isn't considered overflow...?  wacky...

It is. For example -100 + -100 = -200 (less than INT8_MIN; does not
fit). But -1 + -1 = -2, is ok.

-- 
Pedro


Possible missing case for -Wcast-align

2010-04-30 Thread Pedro Pedruzzi

Hi,

gcc (for a STRICT_ALIGNMENT target and with -Wcast-align) do not warn 
about the increasing of alignment requirement on the pointer assignments 
present on the following C code.


struct {
  short var;
} __attribute__((packed)) str;

void fun(void)
{
  short *ptr;
  ptr = (short *) (&str.var);
  ptr = &str.var;
}

Is this the expected behavior in this case?

I don't think so. And I guess gcc is missing it by trusting the type's 
(short) alignment requirement instead of the variable's (str.var 
requires just byte-alignment).


Does anyone think this is an issue?

Regards,
--
Pedro Pedruzzi


Re: anonymous struct

2010-05-03 Thread Pedro Pedruzzi

On 03-05-2010 00:47 wuyin wrote:

struct T{
   int n;
};
struct T1{
   struct T;
} t;
t.n=1;

Please support this grammar.


I believe it _is_ currently supported with -fms-extensions.

See:

http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html

Regards,
--
Pedro Pedruzzi


unexpected warning "comparison of promoted ~unsigned with unsigned warning"

2012-03-06 Thread Pedro Pedruzzi
Hello,

Consider the following test C function:

int f(void)
{
volatile struct {
unsigned char a;
unsigned char b;
} s;

s.a = 0xbc;
s.b = s.a ^ 0xff;

return s.a != (s.b ^ 0xff);
}

When compiled by gcc 4.6.1 with:

gcc -c wpromoted-simple.c -Wsign-compare

I'm getting:

wpromoted-simple.c: In function 'f':
wpromoted-simple.c:11:13: warning: comparison of promoted ~unsigned with
unsigned [-Wsign-compare]

This is unexpected to me. Without the volatile, I don't get the warning.

Is this a different effect of bug #38341 ?

Thanks,
-- 
Pedro Pedruzzi