Re: Manipulating bit fields is behaving inconsistently
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
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
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
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
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
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
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
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?
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