[Bug middle-end/78995] A strange copy error caused by O3 optimization

2017-01-05 Thread zhangfei1 at cffex dot com.cn
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78995

--- Comment #4 from feiz  ---
(In reply to Richard Biener from comment #2)
> static inline void
> rte_memcpy(void *dst, const void *src, size_t n)
> {
> uintptr_t dstu = (uintptr_t)dst;
> uintptr_t srcu = (uintptr_t)src;
> 
> *(uint32_t *)dstu = *(const uint32_t *)srcu;
> 
> this is violating strict aliasing rules as you are copying
> 
> typedef unsigned short  WORD;
> 
> struct TFieldHeader
> {
> WORD FieldID;
> WORD Size;
> };

Well, that's right. I add the compile option  -fno-strict-aliasing, and it
works.
To get a better performance, I got the rte_memcpy code from dpdk codes to
replace memcpy in our project.

Very thanks for your  help. And I have one more question about this.

I check some instruction about aliasing, like 
"Strict aliasing is an assumption, made by the C (or C++) compiler, that
dereferencing pointers to objects of different types will never refer to the
same memory location (i.e. alias eachother.)".

I am confused, we always use the following actions, does this safe?

char  buf[1024];
struct A {
 int a;
 int b;
};

struct p * = (struct A*)buf;
p->a =01;
p->b = 02;

[Bug middle-end/78995] A strange copy error caused by O3 optimization

2017-01-05 Thread zhangfei1 at cffex dot com.cn
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78995

--- Comment #3 from feiz  ---
(In reply to Andrew Pinski from comment #1)
> Does adding -fno-strict-aliasing fix the problem you are seeing?
> 
> I am suspecting the code is violating C/C++ aliasing rules.

Yeah, that's right. I try the -fno-strict-aliasing options, and it works.
Very thanks for your help.

[Bug c++/78995] New: A strange copy error caused by O3 optimization

2017-01-04 Thread zhangfei1 at cffex dot com.cn
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78995

Bug ID: 78995
   Summary: A strange copy error caused by O3 optimization
   Product: gcc
   Version: 4.8.5
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zhangfei1 at cffex dot com.cn
  Target Milestone: ---

Created attachment 40464
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40464=edit
A demon to reproduce this bug

I come across a strange error while using the rte_memcpy function under gcc O3
optimization these days. 

A demon codes are as attachment. The problems are detailed as following,

What I want to do is just to copy 4 Bytes from a buffer to another struct
variable, as the 'key codes' and 'copy function' shown in the tail.
But the source 4 Bytes is 0x11223344, while the copied 4 Bytes is 0x22110040.
What happens?

I have done more test, and the results are as following,

1)  O0 optimization has no error, while O2 and O3 optimization has problem.
2) If I replace the copy function from rte_memcpy to memcpy, there will be no
error.
3) If I directly call the 'GetHeader function' in the constructor function,
there will be no error.
4) If I comment out the change endian codes, there will be no error.
5) If I replace the 'break' by 'return' in 'next function', there will be no
error.


I have done the test in gcc4.4.6 (Redhat6.3-x86_64),  gcc 4.8.5
(Redhat7.2-x86_64), and  gcc 5.2.1 (ubuntu15.10_x86_64). All of them have these
problems. 

To run the demon:
1) just run the ./make.sh will be ok. This will compile the codes, and generate
the target file a.out.



Would anyone give some help to me? 

Very thanks for your help.



/* ***  key codes */
//memcpy(_fieldHeader, m_pCurr, 4);
rte_memcpy(_fieldHeader, m_pCurr, 4);
m_fieldHeader.FieldID = ((m_fieldHeader.FieldID&0x00ff)<<8)|
((m_fieldHeader.FieldID&0xff00)>>8);
m_fieldHeader.Size =((m_fieldHeader.Size&0x00ff)<<8)|
((m_fieldHeader.Size&0xff00)>>8);

char *p = m_pCurr;
fprintf(stdout, "src: 0x%02x%02x%02x%02x\n", *p,*(p+1),*(p+2),*(p+3));

p = (char*)(_fieldHeader);
fprintf(stdout, "dst: 0x%02x%02x%02x%02x\n", *p,*(p+1),*(p+2),*(p+3));

fflush(stdout);

/*  copy function ***/
rte_memcpy(void *dst, const void *src, size_t n)
{
uintptr_t dstu = (uintptr_t)dst;
uintptr_t srcu = (uintptr_t)src;

*(uint32_t *)dstu = *(const uint32_t *)srcu;
}