Bug 25267 - [3.4 4.0 regression] wrong code with inlining at -O2
Summary: [3.4 4.0 regression] wrong code with inlining at -O2
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.5
: P3 critical
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2005-12-05 14:48 UTC by Pierre Chatelier
Modified: 2005-12-05 15:23 UTC (History)
53 users (show)

See Also:
Host: i686 GNU/Linux
Target:
Build:
Known to work: 3.3.6
Known to fail: 3.4.5 4.0.1
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pierre Chatelier 2005-12-05 14:48:31 UTC
Hello,

Consider this code that implements hton and ntoh for float values :

//main.cpp
#include <stdio.h>
#include <netinet/in.h>

inline float hton(float x)
{
  const size_t nb32 = sizeof(float)/sizeof(uint32_t);
  const size_t nb16 = (sizeof(float)/sizeof(uint16_t))%2;
  uint32_t* p32 = (uint32_t*)(&x);
  uint16_t* p16 = 0;
  size_t i = 0;
  for(i = 0 ; i<nb32 ; ++i, ++p32)
    *p32 = htonl(*p32);
  p16 = (uint16_t*)(p32);
  for(i = 0 ; i<nb16 ; ++i, ++p16)
    *p16 = htonl(*p16);
  return x;
}

inline float ntoh(float x)
{
  const size_t nb32 = sizeof(float)/sizeof(uint32_t);
  const size_t nb16 = (sizeof(float)/sizeof(uint16_t))%2;
  uint32_t* p32 = (uint32_t*)(&x);
  uint16_t* p16 = 0;
  size_t i = 0;
  for(i = 0 ; i<nb32 ; ++i, ++p32)
    *p32 = ntohl(*p32);
  p16 = (uint16_t*)(p32);
  for(i = 0 ; i<nb16 ; ++i, ++p16)
    *p16 = ntohl(*p16);
  return x;
}

int main(int argc, char** argv)
{
  float f = 1.3;
  float g = hton(f);
  float h = ntoh(g);
  printf("f=%f\ng=%f\nh=%f\n", f, g, h);
  return 0;
}
///////////////////////////////////////////

When compiled with -O1, it works with gcc 3.3.6, 3.4.5 and 4.0.1
When compiled with -O2, it does not work any more with 3.4.5 and 4.0.1

But if you remove the "inline", it works again at -O2 with 3.4.5 and 4.0.1
In -O3, automatic inlining make it fail again in 3.4.5 and 4.0.1

Regards,

Pierre Chatelier
Comment 1 Pierre Chatelier 2005-12-05 15:04:19 UTC
please consider "*p16 = htons(*p16)" instead of "*p16 = htonl(*p16)", but the problem remains the same.
Comment 2 Andrew Pinski 2005-12-05 15:23:09 UTC
You are violating C/C++ aliasing rules:

inline float hton(float x)
....
  uint32_t* p32 = (uint32_t*)(&x);


You are accessing a float through a uint32_t.

*** This bug has been marked as a duplicate of 21920 ***