[Bug c/93265] New: memcmp comparisons of structs wrapping a primitive type not as compact/efficient as direct comparisons of the underlying primitive type under -Os

pskocik at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Jan 14 14:10:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93265

            Bug ID: 93265
           Summary: memcmp comparisons of structs wrapping a primitive
                    type not as compact/efficient as direct comparisons of
                    the underlying primitive type under -Os
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pskocik at gmail dot com
  Target Milestone: ---

`memcmp` comparisons of types such as `struct Int { int x; };` generate full
`memcmp` calls under `-Os` (also `-O1`)
These are much larger (/less efficient) than the direct primitive-type
comparisons that could have been used.

Example code:

#include <string.h>
//a contiguous struct wrapping a primitive type
typedef struct a_tp { int x; }a_tp; 
_Static_assert(sizeof(a_tp)==sizeof(int),"");

//compare a contiguous lvalue
#define CONTIG_EQ_EH(Ap,Bp) (!memcmp(Ap,Bp,sizeof(*(1?(Ap):(Bp))))) 

/////////////////////////////////////////
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//A FULL MEMCPY :( under -Os (and -O1)
_Bool a_is42(a_tp X) {return CONTIG_EQ_EH(&X,&(a_tp const){42});}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
/////////////////////////////////////////

_Bool i_is42(int X) {return X==42; } //direct cmp
_Bool i2_is42(a_tp X) {return X.x==42; } //same
_Bool i3_is42(a_tp X) {return CONTIG_EQ_EH(&X,&(int const){42});} //still a
direct cmp

https://gcc.godbolt.org/z/BC_QsN


More information about the Gcc-bugs mailing list