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

            Bug ID: 108440
           Summary: rotate optimization may introduce new UB
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kristerw at gcc dot gnu.org
  Target Milestone: ---

GCC optimizes shift instructions to rotate in a way that may make
the optimized IR invoke UB for cases where the original did not.
This can be seen in the IR for f5 from c-c++-common/rotate-1.c:

  unsigned short int
  f5 (unsigned short int x, unsigned int y)
  {
    return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
  }

The IR is doing 32-bit shifts, so y = 16 does not invoke UB:

  short unsigned int f5 (short unsigned int x, unsigned int y)
  {
    int _1;
    int _2;
    signed short _3;
    int _4;
    unsigned int _5;
    int _6;
    signed short _7;
    signed short _8;
    short unsigned int _11;

    <bb 2> :
    _1 = (int) x_9(D);
    _2 = _1 << y_10(D);
    _3 = (signed short) _2;
    _4 = (int) x_9(D);
    _5 = 16 - y_10(D);
    _6 = _4 >> _5;
    _7 = (signed short) _6;
    _8 = _3 | _7;
    _11 = (short unsigned int) _8;
    return _11;
  }

But forwprop1 changes this to a 16-bit rotate which invokes UB for y=16:

  short unsigned int f5 (short unsigned int x, unsigned int y)
  {
    short unsigned int _13;

    <bb 2> :
    _13 = x_9(D) r<< y_10(D);
    return _13;
  }

Reply via email to