GNU 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 |
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 |
Powered by Savane 3.13-d3ae.
Corresponding source code
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])