title: STM32 gcc optimization produces different result
body: <p>I am trying to decode RGB buffer into rows suitable for LED RGB matrix using STM32F4 (gcc in SW4STM32 IDE).
  The code below works perfectly when setting the compiler optimization -O0.</p>
  <p>The code produces different result when compiling with -O1 optimization. (also -O2, -O3).
  The code also produces different result when adding (<strong>attribute</strong>((packed)) to struct color_t definition with -O1.</p>
  <p>The optimization is set to this .c file only, other files are still -O0.</p>
  <p>Could someone spot why the optimization changed code logic/behavior ?</p>
  <pre><code>uint8_t badr[24576] = { 0xff , 0x2a, .... };
  
  struct s_color_t
  {
      uint8_t r;
      uint8_t g;
      uint8_t b;
  } ;
  //__attribute__((packed))
  
  typedef struct s_color_t color_t;
  
  #define WIDTH       128
  #define HEIGHT      64
  #define COLOR_SIZE  sizeof(color_t)
  
  #define R0_POS      0x01
  #define G0_POS      0x02
  #define B0_POS      0x04
  #define R1_POS      0x08
  #define G1_POS      0x10
  #define B1_POS      0x20
  
  #define enc_color(c, s, r)  (c &amp; s)? r : 0
  
  color_t dispBuf[ WIDTH * HEIGHT];
  uint8_t dispLine[WIDTH];
  
  void fillBuf()
  {
      uint8_t *dbuf = (uint8_t *) dispBuf;
      memcpy(dbuf, badr, WIDTH * HEIGHT * COLOR_SIZE);
  }
  
  void enc_row(uint8_t slice, uint16_t row, uint8_t *rBuf)
  {
      uint8_t reg;
  
      color_t *upPtr = dispBuf + row * WIDTH * COLOR_SIZE;
      color_t *dnPtr = dispBuf + (row + (HEIGHT / 2)) * WIDTH * COLOR_SIZE;
      uint8_t *destPtr = rBuf;
  
      uint8_t sn = (1 &lt;&lt; slice);
      for (int i=0; i &lt; WIDTH; i++) {
          reg = 0;
          reg |= enc_color((*upPtr).r, sn, R0_POS);
          reg |= enc_color((*upPtr).g, sn, G0_POS);
          reg |= enc_color((*upPtr).b, sn, B0_POS);
          reg |= enc_color((*dnPtr).r, sn, R1_POS);
          reg |= enc_color((*dnPtr).g, sn, G1_POS);
          reg |= enc_color((*dnPtr).b, sn, B1_POS);
  
          *destPtr = reg;
          upPtr ++;
          dnPtr ++;
          destPtr ++;
      }
  }
  
  void do_func() 
  {
      uint8_t *ptrLine = dispLine;
  
      fillBuf();
      for (int s=0; s &lt; 8; s++) {
          for (int i=0; i&lt; (HEIGHT/2); i++) {
              enc_row(s, i, ptrLine);
              printf(&quot;line %3i &quot;, i);
  
              for(int c=0; c&lt;WIDTH; c++) {
                  printf(&quot;%02X, &quot;, ptrLine[c] &amp; 0xFF);
              }
              printf(&quot;\r\n&quot;);
          }
      }
  }
  </code></pre>