Re: Manipulating bit fields is behaving inconsistently

2016-02-18 Thread Bernd Edlinger
Hi,

> struct fields {
>   long long unsigned f0:12;
>   long long unsigned f1:52;
> } __attribute__((__packed__));

the C99 standard ISO/IEC 9899 forbids this type:

6.7.2.1 Structure and union specifiers

4 A bit-field shall have a type that is a qualified or unqualified version of 
_Bool, signed int,
   unsigned int, or some other implementation-defined type.

The C standard simply does not promote the bit-field value to any type larger 
than int or
unsigned int.

GCC chooses to do the larger than int computations in an artificial 52-bit 
type, but it is a
non-standard extension.

And if you compile your example with -Wall you'll see the problem:

gcc -m32 -O3 -Wall  test.c
test.c: In function 'main':
test.c:17:21: warning: format '%llx' expects argument of type 'long long 
unsigned int', but argument 2 has type 'int' [-Wformat=]
   printf("x.f0=0x%llx\n", x.f0);
 ^
test.c:19:21: warning: format '%llx' expects argument of type 'long long 
unsigned int', but argument 2 has type 'long long unsigned int:52' [-Wformat=]
   printf("x.f1=0x%llx\n", x.f1);
 ^

so especially the first warning is no joke:

./a.out 
x.f0=0x80497b40fff
  g0=0x1ffe expect 0x1ffe
x.f1=0xf
  g1=0xe expect 0x1e


OTOH that is perfectly OK for C++:

gcc -x c++ -m32 -O3 -Wall  test.c

./a.out 
x.f0=0xfff
  g0=0x1ffe expect 0x1ffe
x.f1=0xf
  g1=0x1e expect 0x1e


Regards
Bernd.

Need suggestion about bug 68425

2016-02-18 Thread Prasad Ghangal
I was looking at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68425

For testcase

const int array[2] = { 1, 2, 3 ,6 ,89 ,193};


gcc 6.0.0 produces warnings like (spacing may get disturbed by gmail) :

68425.c: In function ‘main’:
68425.c:3:34: warning: excess elements in array initializer
 const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
   ^
68425.c:3:34: note: (near initialization for ‘array’)
68425.c:3:37: warning: excess elements in array initializer
 const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
   ^
68425.c:3:37: note: (near initialization for ‘array’)
68425.c:3:40: warning: excess elements in array initializer
 const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
   ^~
68425.c:3:40: note: (near initialization for ‘array’)
68425.c:3:44: warning: excess elements in array initializer
 const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
^~~
68425.c:3:44: note: (near initialization for ‘array’)


While clang gives :

68425.c:3:34: warning: excess elements in array initializer
const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
  ^
1 warning generated.


Wouldn't it be nice instead of multiple warnings if gcc gives single
warning like :

68425.c:3:34: warning: excess elements in array initializer (6
elements, expected 2)
const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
  ^




-- 
Thanks and Regards,
Prasad Ghangal


Re: Help with building MEM_REF node

2016-02-18 Thread Richard Biener
On Wed, Feb 17, 2016 at 5:27 PM, Cristina Georgiana Opriceana
 wrote:
> Hello,
>
> I inserted a new local var decl in gimple, a pointer which is
> malloc'ed and now I am trying to read/write in that memory.
>
> int *mumu;
> mumu = malloc ( 40 * sizeof (int));
> mumu[1] = 10;
>
> The following statement: mumu[1] = 10; which should look like this
> MEM[(int *)mumu_10 + 4B] = 10;
>
> for me, looks like:
> MEM[(int * *)mumu_10 + 4B] = 10;
>
> This is the variable insertion:
> tree vardecl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
> VAR_DECL, get_identifier ("mumu"),
> integer_ptr_type_node);
> TREE_ADDRESSABLE (vardecl) = 1;
> DECL_CONTEXT (vardecl) = current_function_decl;
> TREE_USED (vardecl) = 1;
> add_local_decl (cfun, vardecl);
>
> Then I insert the malloc call:
>
> tree fn_ptr = make_ssa_name (vardecl);
> fn = builtin_decl_explicit (BUILT_IN_MALLOC);
> size = build_int_cst (integer_type_node, 40 * sizeof(int)); // testing purpose
> gimple *malloc_stmt = gimple_build_call (fn, 1, size);
> gimple_call_set_lhs (malloc_stmt, fn_ptr);
> gsi_insert_before (&gsi, malloc_stmt, GSI_SAME_STMT);
>
> And then I try to build a mem_ref to the pointer ssa:
>
> tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (fn_ptr), fn_ptr,
>build_int_cst (build_pointer_type (TREE_TYPE (fn_ptr)), 
> 4));

as you want to dereference the pointer you want TREE_TYPE (TREE_TYPE
(fn_ptr)) here (int).
And for the last operand do not indirect fn_ptr again.

> gimple *stmt = gimple_build_assign (mem_ref, build_int_cst
>   (integer_type_node,10));
> gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
>
>
> If i use build2() instead of fold_build2() compilation fails with
> error: non-trivial conversion at assignment
> void *
> int
> # .MEM_12 = VDEF <.MEM_2>
> MEM[(int * *)mumu_10 + 4B] = 10;

As expected.

> I am a newbie to gcc development, any info is appreciated.
> Thanks,
> Cristina


Re: Need suggestion about bug 68425

2016-02-18 Thread Manuel López-Ibáñez

On 18/02/16 11:40, Prasad Ghangal wrote:

Wouldn't it be nice instead of multiple warnings if gcc gives single
warning like :

68425.c:3:34: warning: excess elements in array initializer (6
elements, expected 2)
 const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
   ^


Yes! Perhaps even (now that we have ranges!):

68425.c:3:34: warning: excess elements in array initializer (6 elements, 
expected 2)

  const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
   ^

But even without ranges, your suggestion would be a great improvement.

Cheers,

Manuel.


Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-18 Thread Michael Matz
Hi,

On Tue, 16 Feb 2016, H.J. Lu wrote:

> Here is the new definition:
> 
> An empty type is a type where it and all of its subobjects (recursively) 
> are of class, structure, union, or array type.  No memory slot nor 
> register should be used to pass or return an object of empty type.

The trivially copyable is gone again.  Why is it not necessary?


Ciao,
Michael.


Re: Manipulating bit fields is behaving inconsistently

2016-02-18 Thread Wink Saville
You've convinced me that this isn't a bug, but I assume you'd agree
its weird at best. I tested it with clang and it works as I'd expect:

$ make
clang -x c -m64 -O3 -Wall -o test.o -c test.c
objdump -d test.o > test.txt
clang -m64 -O3 -Wall test.o -o test
wink@wink-desktop:~/prgs/large_fields_are_odd
$ ./test
x.f0=0xfff
  g0=0x1ffe expect 0x1ffe
x.f1=0xf
  g1=0x1e expect 0x1e

Here is the make file:

CC = clang
CFLAGS = -m64 -O3 -Wall

all: test

test.o: test.c
$(CC) -x c $(CFLAGS) -o test.o -c test.c
objdump -d test.o > test.txt

test: test.o
$(CC) $(CFLAGS) test.o -o test

clean:
rm -f test test.o test.txt


Do you think gcc should change?

On Thu, Feb 18, 2016 at 2:52 AM, Bernd Edlinger
 wrote:
> Hi,
>
>> struct fields {
>>   long long unsigned f0:12;
>>   long long unsigned f1:52;
>> } __attribute__((__packed__));
>
> the C99 standard ISO/IEC 9899 forbids this type:
>
> 6.7.2.1 Structure and union specifiers
>
> 4 A bit-field shall have a type that is a qualified or unqualified version of 
> _Bool, signed int,
>unsigned int, or some other implementation-defined type.
>
> The C standard simply does not promote the bit-field value to any type larger 
> than int or
> unsigned int.
>
> GCC chooses to do the larger than int computations in an artificial 52-bit 
> type, but it is a
> non-standard extension.
>
> And if you compile your example with -Wall you'll see the problem:
>
> gcc -m32 -O3 -Wall  test.c
> test.c: In function 'main':
> test.c:17:21: warning: format '%llx' expects argument of type 'long long 
> unsigned int', but argument 2 has type 'int' [-Wformat=]
>printf("x.f0=0x%llx\n", x.f0);
>  ^
> test.c:19:21: warning: format '%llx' expects argument of type 'long long 
> unsigned int', but argument 2 has type 'long long unsigned int:52' [-Wformat=]
>printf("x.f1=0x%llx\n", x.f1);
>  ^
>
> so especially the first warning is no joke:
>
> ./a.out
> x.f0=0x80497b40fff
>   g0=0x1ffe expect 0x1ffe
> x.f1=0xf
>   g1=0xe expect 0x1e
>
>
> OTOH that is perfectly OK for C++:
>
> gcc -x c++ -m32 -O3 -Wall  test.c
>
> ./a.out
> x.f0=0xfff
>   g0=0x1ffe expect 0x1ffe
> x.f1=0xf
>   g1=0x1e expect 0x1e
>
>
> Regards
> Bernd.


Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-18 Thread H.J. Lu
On Thu, Feb 18, 2016 at 6:35 AM, Michael Matz  wrote:
> Hi,
>
> On Tue, 16 Feb 2016, H.J. Lu wrote:
>
>> Here is the new definition:
>>
>> An empty type is a type where it and all of its subobjects (recursively)
>> are of class, structure, union, or array type.  No memory slot nor
>> register should be used to pass or return an object of empty type.
>
> The trivially copyable is gone again.  Why is it not necessary?
>

I think we want to cover

struct
{
  unsigned int : 8;
};

but not

struct
{
  unsigned int  i :8;
};

" trivially copyable" applies to both.

-- 
H.J.


Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-18 Thread Richard Smith
On Thu, Feb 18, 2016 at 6:35 AM, Michael Matz  wrote:
> Hi,
>
> On Tue, 16 Feb 2016, H.J. Lu wrote:
>
>> Here is the new definition:
>>
>> An empty type is a type where it and all of its subobjects (recursively)
>> are of class, structure, union, or array type.  No memory slot nor
>> register should be used to pass or return an object of empty type.
>
> The trivially copyable is gone again.  Why is it not necessary?

The C++ ABI doesn't defer to the C psABI for types that aren't
trivially-copyable. See
http://mentorembedded.github.io/cxx-abi/abi.html#normal-call


How to efficiently unpack 8 bytes from a 64-bit integer?

2016-02-18 Thread Phil Ruffwind
Hello all,

I am trying to analyze the optimized results of following code.  The
intent is to unpack a 64-bit integer into a struct containing eight
8-bit integers.  The optimized result was very promising at first, but
I then discovered that whenever the unpacking function gets inlined
into another function, the optimization no longer works.

/* a struct of eight 8-bit integers */
struct alpha {
int8_t a;
int8_t b;
...
int8_t h;
};

struct alpha unpack(uint64_t x)
{
struct alpha r;
memcpy(&r, &x, 8);
return r;
}

struct alpha wrapper(uint64_t y)
{
return unpack(y);
}

The code was compiled with gcc 5.3.0 on Linux 4.4.1 with -O3 on x86-64.

The `unpack` function optimizes fine.  It produces the following
assembly as expected:

mov rax, rdi
ret

Given that `wrapper` is a trivial wrapper around `unpack`, I would
expect the same.  But in reality this is what I got from gcc:

mov eax, edi
xor ecx, ecx
mov esi, edi
shr ax, 8
mov cl, dil
shr esi, 24
mov ch, al
mov rax, rdi
movzx edx, sil
and eax, 16711680
and rcx, -16711681
sal rdx, 24
movabs rsi, -4278190081
or rcx, rax
mov rax, rcx
movabs rcx, -1095216660481
and rax, rsi
or rax, rdx
movabs rdx, 1095216660480
and rdx, rdi
and rax, rcx
movabs rcx, -280375465082881
or rax, rdx
movabs rdx, 280375465082880
and rdx, rdi
and rax, rcx
movabs rcx, -71776119061217281
or rax, rdx
movabs rdx, 71776119061217280
and rdx, rdi
and rax, rcx
shr rdi, 56
or rax, rdx
sal rdi, 56
movabs rdx, 72057594037927935
and rax, rdx
or rax, rdi
ret

This seems quite strange.  Somehow the inlining process seems to have
screwed up the potential optimizations.  Is there a someway to prevent
this from happening short of disabling inlining?  Or perhaps there is
a better way to write this code so that gcc would optimize more
predictably?

I would appreciate any advice, thanks.

Phil