[Bug tree-optimization/83389] std::tie generates sub-optimal code when used to compare POD fields

2017-12-12 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83389

--- Comment #4 from Luca Stoppa  ---
(In reply to Jonathan Wakely from comment #2)
> This isn't a libstdc++ bug. std::tie is doing exactly what it's meant to do,
> which is generate a tuple of references, so of course it's not the same as
> comparing the original objects (because in the general case the references
> aren't all bound to members of the same object).
I see. Thanks for your detailed answer. I agree that using std::tie as a
surrogate for operator==() probably isn't the first usecase that comes to mind.
Please, feel free to close this missed-optimization.

> 
> Reduced:
> 
> struct data { int x, y; char c1, c2; };
> 
> struct tuple { const int &x, &y; const char &c1, &c2; };
> 
> bool operator==(const tuple& l, const tuple& r) {
>   return l.x == r.x && l.y == r.y && l.c1 == r.c1 && l.c2 == r.c2;
> }
> 
> bool operator==(const data& l, const data& r) {
>   return l.x == r.x && l.y == r.y && l.c1 == r.c1 && l.c2 == r.c2;
> }
> 
> bool compare(const data& l, const data& r) {
>   return tuple{l.x, l.y, l.c1, l.c2} == tuple{r.x, r.y, r.c1, r.c2};
> }
> 
> int main()
> {
> data d1{1,2,'a','b'};
> data d2{1,2,'a','d'};
> 
> return (compare(d1,d2) ? 0 : -1);
> }

[Bug libstdc++/83389] std::tie generates sub-optimal code when used to compare POD fields

2017-12-12 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83389

--- Comment #1 from Luca Stoppa  ---
Created attachment 42846
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42846&action=edit
Generated assembler file

The code was compiled with
g++ -std=c++17 -O3 -S sample.cpp

g++ --version:
g++ (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[Bug libstdc++/83389] New: std::tie generates sub-optimal code when used to compare POD fields

2017-12-12 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83389

Bug ID: 83389
   Summary: std::tie generates sub-optimal code when used to
compare POD fields
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lucanus81 at gmail dot com
  Target Milestone: ---

Created attachment 42845
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42845&action=edit
cpp file with the example

Let's consider a simple struct with two integers:
struct data { int x, y; };

Let's suppose we want to write a comparison operator. A first attempt might be
bool operator==(data const& d1, data const& d2) {
  return d1.x == d2.x && d1.y == d2.y
}

An alternative approach (maybe this is a "bad" approach? )might be to use
std::tie.

bool operator==(data const& d1, data const& d2) {
  return std::tie(d1.x, d1.y) == 
 std::tie(d2.x, d2.y);
}

At O3 gcc 7.2 generates exactly the same code. So far so good.
Let's suppose now that we want to add a couple of char fields:
struct data { int x, y; char c1, c2; };

At this point gcc starts generating sub-optimal assembler in the sense it fails
to see that c1 and c2 are stored into a contiguous memory address and could be
compared with a single CMP WORD PTR instruction instead of two CMP BYTE PTR
(one for each byte).

For operator==() I see the compiler was able to generate a cmpw (where both
bytes are packed and compared together)
movl4(%rsi), %ecx
cmpl%ecx, 4(%rdi)
jne .L1
movzwl  8(%rsi), %eax
cmpw%ax, 8(%rdi)
sete%al
ret

while for the std::tie example we generate two cmpb instructions:
movl4(%rsi), %ecx
cmpl%ecx, 4(%rdi)
jne .L7
movzbl  8(%rsi), %ecx
cmpb%cl, 8(%rdi)
jne .L7
movzbl  9(%rsi), %eax
cmpb%al, 9(%rdi)
sete%al
ret

I don't really fully understand if this is a potential problem or simply it's a
"Working As Designed" but I believe that the compiler for std::tie when all
types are POD should be able to generate exactly the same code as operator==().

[Bug c++/78491] invalid conversion from 'const void*' to 'void*'

2016-11-23 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78491

--- Comment #2 from Luca Stoppa  ---
Just wanted to add that changing the vector element from "const std::string" to
"std::string" seems to fix this issue.

[Bug c++/78491] invalid conversion from 'const void*' to 'void*'

2016-11-23 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78491

--- Comment #1 from Luca Stoppa  ---
Created attachment 40126
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40126&action=edit
full error message

[Bug c++/78491] New: invalid conversion from 'const void*' to 'void*'

2016-11-23 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78491

Bug ID: 78491
   Summary: invalid conversion from 'const void*' to 'void*'
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lucanus81 at gmail dot com
  Target Milestone: ---

Created attachment 40125
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40125&action=edit
test case

when compiling the testcase attached here I get:
#include 
#include 
#include 

void lprintc(const std::vector &vect) {
  for (const auto &s1 : vect)
std::cout << s1 << std::endl;
}

int main() {
  const std::vector lines = { "one", "two", "three" };
  lprintc(lines);

  return 0;
}

/usr/local/gcc-head/include/c++/7.0.0/ext/new_allocator.h:121:23: error:
invalid conversion from 'const void*' to 'void*' [-fpermissive]
  ::operator delete(__p, std::align_val_t(alignof(_Tp)));
(plus many more lines: see full_error.txt attached)

I can see this error with any version. clang correctly accepts this code.
I don't know whether this is a bug or not.

Thanks

[Bug c++/78399] g++ generates sub-optimal assembler code when structs aren't explicitly aligned.

2016-11-17 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78399

--- Comment #1 from Luca Stoppa  ---
Created attachment 40071
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40071&action=edit
Optimal code

[Bug c++/78399] New: g++ generates sub-optimal assembler code when structs aren't explicitly aligned.

2016-11-17 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78399

Bug ID: 78399
   Summary: g++ generates sub-optimal assembler code when structs
aren't explicitly aligned.
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lucanus81 at gmail dot com
  Target Milestone: ---

Created attachment 40070
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40070&action=edit
suboptimal code

Consider the following example:

struct pod { char x[7]; };
pod copy_pod(pod d) { return d; }

gcc (at any optimization level) will general sub-optimal assembler code (see
attachment).
The interesting thing is that if we change "pod" to contain a number of bytes
that fit into a cpu register (2, 4, 8, 16, 32, 64) then the generated assembler
is optimal (see attachment)

struct pod { char x[8]; };
pod copy_pod(pod d) { return d; }

One workaround I found is to explicitly use alignas:
struct alignas(8) pod { char x[7]; }; 

I'm wondering whether gcc should generate optimal code even without alignas(8).

[Bug c++/78391] g++ (any version) at O0 (for O1, O2, O3 is ok) doesn't warn when class members are used uninitialized.

2016-11-17 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78391

--- Comment #2 from Luca Stoppa  ---
(In reply to Richard Biener from comment #1)
> -Wuninitialized requires optimization to handle this case.

I see thanks. Considering that I found this bug in our unit tests, I'll simply
add -O1 in order to avoid in the future this issue in our code.

[Bug c++/78391] New: g++ (any version) at O0 (for O1, O2, O3 is ok) doesn't warn when class members are used uninitialized.

2016-11-17 Thread lucanus81 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78391

Bug ID: 78391
   Summary: g++ (any version) at O0 (for O1, O2, O3 is ok) doesn't
warn when class members are used uninitialized.
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lucanus81 at gmail dot com
  Target Milestone: ---

Created attachment 40063
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40063&action=edit
Minimal testcase that shows the (possible) problem.

It seems like g++ (any version) doesn't warn when class members are
uninitialized when no optimization is enabled (and at -O0). For -O1, -O2, -O3
we correctly get a warning (On the contrary, clang, any version, reports a
warning at any optimization level).

struct data { int x=w; int w=10; };

int main() {
data d;
return d.x;
}

g++ ub.cpp -Wall -Wextra -std=gnu++1z -O0 
=> no warning

g++ ub.cpp -Wall -Wextra -std=gnu++1z -O1
=> 
ub.cpp: In function 'int main()':
ub.cpp:4:10: warning: 'd.data::w' is used uninitialized in this function
[-Wuninitialized]
 data d;

for -O2, -O3 we get exactly the same warning.