bugGNU Development Chain for 68HC11/68HC12 - Bugs: bug #16201, Local byte array incorrectly...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #16201: Local byte array incorrectly optimized into word register

Submitter:  Stephen Glow <sglow>
Submitted:  Tue 28 Mar 2006 03:32:57 PM UTC
   
 
Category:  gcc Severity:  3 - Normal
Item Group:  sw-bug Status:  None
Privacy:  Public Assigned to:  None
Open/Closed:  Open

Tue 28 Mar 2006 03:32:57 PM UTC, original submission:  

Here  is a simple test program the shows the problem:

---------------------------------------------------------------------------------
typedef unsigned char  uint8_t;

void test( uint8_t tq, uint8_t ts1, uint8_t ts2, uint8_t sjw, uint8_t samp, uint8_t *output )
{
  uint8_t btr[2];

  btr[0] = (sjw<<6) | tq;
  btr[1] = (samp<<7) | (ts2<<4) | ts1;

  output[0] = btr[0];
  output[1] = btr[1];
  return;
}
---------------------------------------------------------------------------------

It seems that the compiler optimizes the two byte local array (btr[2]) into a single word register.  It clears the upper half of the array (btr[0]) when it updates the value of the lower half (btr[1]).  The result is correct for the second byte, but zero for the first.

Here is the assembly dump that the compiler generates, and the RTL generated by adding the -dr command line option to the compiler.



;;;-----------------------------------------
;;; Start MC68HCS12 gcc assembly output
;;; gcc compiler 3.3.6-m68hc1x-20060122
;;; Command:    /usr/lib/gcc-lib/m6811-elf/3.3.6-m68hc1x-20060122/cc1 -quiet -Iinc -I../LinuxDriver/inc -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6 -Dmc68hc1x -D__mc68hc1x__ -D__mc68hc1x -D__HAVE_SHORT_INT__ -D__INT__=16 -Dmc6812 -DMC6812 -Dmc68hcs12 c/test.c -quiet -dumpbase test.c -mshort -m68hcs12 -auxbase-strip obj/test -g -Os -Wall -W -Wpointer-arith -fomit-frame-pointer -fverbose-asm -o obj/test.asm
;;; Compiled:    Sat Mar 25 09:49:21 2006
;;; (META)compiled by GNU C version 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8).
;;;-----------------------------------------
   .file    "test.c"
   .mode mshort
; GNU C version 3.3.6-m68hc1x-20060122 (m6811-elf)
;    compiled by GNU C version 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8).
; GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129454
; options passed:  -Iinc -I../LinuxDriver/inc -D__GNUC__=3
; -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6 -Dmc68hc1x -D__mc68hc1x__
; -D__mc68hc1x -D__HAVE_SHORT_INT__ -D__INT__=16 -Dmc6812 -DMC6812
; -Dmc68hcs12 -mshort -m68hcs12 -auxbase-strip -g -Os -Wall -W
; -Wpointer-arith -fomit-frame-pointer -fverbose-asm
; options enabled:  -fdefer-pop -fomit-frame-pointer
; -foptimize-sibling-calls -fcse-follow-jumps -fcse-skip-blocks
; -fexpensive-optimizations -fthread-jumps -fstrength-reduce -fpeephole
; -fforce-mem -ffunction-cse -fkeep-static-consts -fcaller-saves
; -fpcc-struct-return -fgcse -fgcse-lm -fgcse-sm -floop-optimize
; -fcrossjumping -fif-conversion -fif-conversion2 -frerun-cse-after-loop
; -frerun-loop-opt -fdelete-null-pointer-checks -fsched-interblock
; -fsched-spec -fbranch-count-reg -freorder-functions -fcprop-registers
; -fcommon -fverbose-asm -fgnu-linker -fregmove -foptimize-register-move
; -fargument-alias -fstrict-aliasing -fmerge-constants
; -fzero-initialized-in-bss -fident -fpeephole2 -fguess-branch-probability
; -fmath-errno -ftrapping-math -mshort -mrelax -m68hc12 -m68hcs12 -m6812
; -m68S12 -msoft-reg-count=0

   .section    .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
   .section    .debug_info,"",@progbits
.Ldebug_info0:
   .section    .debug_line,"",@progbits
.Ldebug_line0:
   .sect    .text
.Ltext0:
   .globl    test
   .type    test,@function
test:
.LFB3:
.LM1:
   leas    -7,sp
   stab    6,sp    ;  tq
   ldx    17,sp    ;  output,  output
.LM2:
   stx    _.xy
.LBB2:
   xgdx
   clra
   ldab    14,sp    ;  sjw
   ldx    _.xy
   asld
   asld
   asld
   asld
   asld
   asld
   std    2,sp
   ldab    6,sp    ;  tq
   orab    3,sp
   tba
   clrb
   xgdy
   anda    #0
   andb    #-1
   xgdy
   pshy    ;  btr
   oraa    1,sp+
   orab    1,sp+
   tfr    d,y    ;  btr
.LM3:
   clra
   ldab    16,sp    ;  samp
   asld
   asld
   asld
   asld
   asld
   asld
   asld
   std    4,sp    ;  samp
   clra
   ldab    12,sp    ;  ts2
   asld
   asld
   asld
   asld
   orab    5,sp
   orab    10,sp    ;  ts1
   tfr    d,y    ;  btr,  btr
.LM4:
   sty    _.tmp    ;  btr
   ldab    _.tmp
   clra
   stab    0,x    ; * output
.LM5:
   xgdy
   stab    1,x
   xgdy
.LM6:
   leas    7,sp
   rts

--------------------------------------------------------------------------------------------------
RTL output


;; Function test

(note 1 0 2 ("c/test.c") 4)

(note 2 1 3 NOTE_INSN_DELETED)

(insn 3 2 4 (nil) (set (reg/v:QI 53)
       (reg:QI 1 d)) -1 (nil)
   (nil))

(insn 4 3 5 (nil) (set (reg/v:QI 54)
       (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 1 [0x1])) [0 ts1+0 S1 A8])) -1 (nil)
   (expr_list:REG_EQUIV (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 1 [0x1])) [0 ts1+0 S1 A8])
       (nil)))

(insn 5 4 6 (nil) (set (reg/v:QI 55)
       (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 3 [0x3])) [0 ts2+0 S1 A8])) -1 (nil)
   (expr_list:REG_EQUIV (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 3 [0x3])) [0 ts2+0 S1 A8])
       (nil)))

(insn 6 5 7 (nil) (set (reg/v:QI 56)
       (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 5 [0x5])) [0 sjw+0 S1 A8])) -1 (nil)
   (expr_list:REG_EQUIV (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 5 [0x5])) [0 sjw+0 S1 A8])
       (nil)))

(insn 7 6 8 (nil) (set (reg/v:QI 57)
       (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 7 [0x7])) [0 samp+0 S1 A8])) -1 (nil)
   (expr_list:REG_EQUIV (mem/f:QI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 7 [0x7])) [0 samp+0 S1 A8])
       (nil)))

(insn 8 7 9 (nil) (set (reg/v/f:HI 58)
       (mem/f:HI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 8 [0x8])) [2 output+0 S2 A8])) -1 (nil)
   (expr_list:REG_EQUIV (mem/f:HI (plus:HI (reg/f:HI 48 virtual-incoming-args)
               (const_int 8 [0x8])) [2 output+0 S2 A8])
       (nil)))

(note 9 8 10 NOTE_INSN_FUNCTION_BEG)

(note 10 9 11 NOTE_INSN_DELETED)

(note 11 10 12 0xb7f86318 NOTE_INSN_BLOCK_BEG)

(note 12 11 13 NOTE_INSN_DELETED)

(note 13 12 14 ("c/test.c") 5)

(note 14 13 15 ("c/test.c") 7)

(insn 15 14 16 (nil) (set (reg:HI 60)
       (zero_extend:HI (reg/v:QI 56))) -1 (nil)
   (nil))

(insn 16 15 17 (nil) (set (reg:HI 61)
       (ashift:HI (reg:HI 60)
           (const_int 6 [0x6]))) -1 (nil)
   (nil))

(insn 17 16 18 (nil) (set (reg:QI 62)
       (ior:QI (reg/v:QI 53)
           (subreg:QI (reg:HI 61) 1))) -1 (nil)
   (nil))

(insn 18 17 19 (nil) (set (reg:HI 63)
       (zero_extend:HI (reg:QI 62))) -1 (nil)
   (nil))

(insn 19 18 20 (nil) (set (reg:HI 64)
       (ashift:HI (reg:HI 63)
           (const_int 8 [0x8]))) -1 (nil)
   (nil))

(insn 20 19 21 (nil) (set (reg/v:HI 59)
       (and:HI (reg/v:HI 59)
           (const_int 255 [0xff]))) -1 (nil)
   (nil))

(insn 21 20 22 (nil) (set (reg/v:HI 59)
       (ior:HI (reg/v:HI 59)
           (reg:HI 64))) -1 (nil)
   (nil))

(note 22 21 23 ("c/test.c") 8)

(insn 23 22 24 (nil) (set (reg:HI 65)
       (zero_extend:HI (reg/v:QI 57))) -1 (nil)
   (nil))

(insn 24 23 25 (nil) (set (reg:HI 66)
       (ashift:HI (reg:HI 65)
           (const_int 7 [0x7]))) -1 (nil)
   (nil))

(insn 25 24 26 (nil) (set (reg:HI 67)
       (zero_extend:HI (reg/v:QI 55))) -1 (nil)
   (nil))

(insn 26 25 27 (nil) (set (reg:HI 68)
       (ashift:HI (reg:HI 67)
           (const_int 4 [0x4]))) -1 (nil)
   (nil))

(insn 27 26 28 (nil) (set (reg:QI 69)
       (ior:QI (subreg:QI (reg:HI 66) 1)
           (subreg:QI (reg:HI 68) 1))) -1 (nil)
   (nil))

(insn 28 27 29 (nil) (set (reg:QI 70)
       (ior:QI (reg:QI 69)
           (reg/v:QI 54))) -1 (nil)
   (nil))

(insn 29 28 30 (nil) (set (strict_low_part (subreg:QI (reg/v:HI 59) 1))
       (reg:QI 70)) -1 (nil)
   (nil))

(note 30 29 31 ("c/test.c") 10)

(insn 31 30 32 (nil) (set (reg:HI 71)
       (lshiftrt:HI (reg/v:HI 59)
           (const_int 8 [0x8]))) -1 (nil)
   (nil))

(insn 32 31 33 (nil) (set (mem:QI (reg/v/f:HI 58) [0 S1 A8])
       (subreg:QI (reg:HI 71) 1)) -1 (nil)
   (nil))

(note 33 32 34 ("c/test.c") 11)

(insn 34 33 35 (nil) (set (mem:QI (plus:HI (reg/v/f:HI 58)
               (const_int 1 [0x1])) [0 S1 A8])
       (subreg:QI (reg/v:HI 59) 1)) -1 (nil)
   (nil))

(note 35 34 36 ("c/test.c") 12)

(jump_insn 36 35 37 (nil) (set (pc)
       (label_ref 41)) -1 (nil)
   (nil))

(barrier 37 36 38)

(note 38 37 39 0xb7f86318 NOTE_INSN_BLOCK_END)

(note 39 38 40 NOTE_INSN_FUNCTION_END)

(note 40 39 41 ("c/test.c") 13)

(code_label 41 40 0 1 "" [0 uses])

Stephen Glow <sglow>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

CC list is empty

 

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

 

Follows 1 latest change.

Date Changed by Updated Field Previous Value => Replaced by
2006-03-28 sglow Carbon-Copy- Added sglow

Back to the top

Powered by Savane 3.13-4448.
Corresponding source code