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

            Bug ID: 115717
           Summary: volatile store hampering unrelated optimization
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

Created attachment 58542
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58542&action=edit
C test case

Test case:

typedef __UINT8_TYPE__ uint8_t;

uint8_t val;
uint8_t volatile vol;

void func (uint8_t x) {
    x >>= 1;
    val = 1 << x;
}

void func_vol (uint8_t x) {
    x >>= 1;
    vol = 1 << x;
}

and compiled with:

$ avr-gcc -S -Os -dp -fdump-tree-all -da

In func(), the computation of "1 << x" is performed as an 8-bit value (avr has
no barrel shifter, so it has to be performed in a loop):

func:
        lsr r24          ;  22  [c=4 l=1]  *lshrqi3/2
        ldi r25,lo8(1)   ;  23  [c=4 l=1]  movqi_insn/1
        rjmp 2f          ;  24  [c=16 l=4]  *ashlqi3/0
1:      
        lsl r25 
2:      
        dec r24 
        brpl 1b 
        sts val,r25      ;  25  [c=4 l=2]  movqi_insn/2
/* epilogue start */
        ret              ;  28  [c=0 l=1]  return

However when the stored-to value is volatile, then the loop shifts a 16-bit
value, which just wastes code and time:

func_vol:
        lsr r24          ;  19  [c=4 l=1]  *lshrqi3/2
        ldi r18,lo8(1)   ;  20  [c=4 l=2]  *movhi/4
        ldi r19,0       
        mov r20,r18      ;  21  [c=4 l=2]  *movhi/0
        mov r21,r19
        rjmp 2f          ;  22  [c=20 l=5]  *ashlhi3/0
1:      
        lsl r20
        rol r21
2:      
        dec r24 
        brpl 1b 
        sts vol,r20      ;  24  [c=4 l=2]  movqi_insn/2
/* epilogue start */
        ret              ;  27  [c=0 l=1]  return

The tree-dumps show no difference, so the optimization is supposed to be
performed by some RTL pass (insn combine?).

Reply via email to