[Bug target/53987] [SH] Unnecessary zero-extensions
olegendo at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jan 15 01:37:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987
--- Comment #9 from Oleg Endo <olegendo at gcc dot gnu.org> ---
Another related issue is this example function:
unsigned char h (unsigned char a, int b)
{
return (unsigned char)(a + b);
}
compiling with -O2 -mrenesas (which allows undefined high bits in the return
value):
extu.b r4,r4 << not needed
mov r5,r0
rts
add r4,r0
It seems that the fwprop1 pass causes this.
The initial RTL for this looks like this:
(insn 2 5 3 2 (set (reg/v:SI 165 [ a ])
(zero_extend:SI (reg:QI 4 r4 [ a ]))) sh_tmp.cpp:1550 -1
(nil))
(insn 3 2 4 2 (set (reg/v:SI 166 [ b ])
(reg:SI 5 r5 [ b ])) sh_tmp.cpp:1550 -1
(nil))
(note 4 3 7 2 NOTE_INSN_FUNCTION_BEG)
(insn 7 4 8 2 (set (reg:QI 168)
(subreg:QI (reg/v:SI 166 [ b ]) 0)) sh_tmp.cpp:1551 -1
(nil))
(insn 8 7 9 2 (set (reg:SI 169)
(plus:SI (reg/v:SI 165 [ a ])
(subreg:SI (reg:QI 168) 0))) sh_tmp.cpp:1551 -1
(nil))
(insn 9 8 13 2 (set (reg:QI 164 [ <retval> ])
(subreg:QI (reg:SI 169) 0)) sh_tmp.cpp:1551 -1
(nil))
(insn 13 9 14 2 (set (reg/i:QI 0 r0)
(reg:QI 164 [ <retval> ])) sh_tmp.cpp:1552 -1
(nil))
(insn 14 13 0 2 (use (reg/i:QI 0 r0)) sh_tmp.cpp:1552 -1
(nil))
Notice that the plus op is expanded as a subreg:SI (reg:QI) and the result is
then taken as a subreg:QI. This should be OK with the addsi3 pattern.
However, fwprop1 then propagates the hardregs and eliminates the subregs:
(note 5 0 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn 2 5 3 2 (set (reg/v:SI 165 [ a ])
(zero_extend:SI (reg:QI 4 r4 [ a ]))) sh_tmp.cpp:1550 218
{*zero_extendqisi2_compact}
(expr_list:REG_DEAD (reg:QI 4 r4 [ a ])
(nil)))
(insn 3 2 4 2 (set (reg/v:SI 166 [ b ])
(reg:SI 5 r5 [ b ])) sh_tmp.cpp:1550 252 {movsi_ie}
(expr_list:REG_DEAD (reg:SI 5 r5 [ b ])
(nil)))
(note 4 3 8 2 NOTE_INSN_FUNCTION_BEG)
(insn 8 4 13 2 (set (reg:SI 169)
(plus:SI (reg/v:SI 165 [ a ])
(reg/v:SI 166 [ b ]))) sh_tmp.cpp:1551 63 {*addsi3_compact}
(expr_list:REG_DEAD (reg:QI 168 [ b ])
(expr_list:REG_DEAD (reg/v:SI 165 [ a ])
(nil))))
(insn 13 8 14 2 (set (reg/i:QI 0 r0)
(subreg:QI (reg:SI 169) 0)) sh_tmp.cpp:1552 270 {*movqi}
(expr_list:REG_DEAD (reg:SI 169)
(nil)))
(insn 14 13 0 2 (use (reg/i:QI 0 r0)) sh_tmp.cpp:1552 -1
(nil))
After that, everything is pretty much set and the zero extension will not be
eliminated anymore.
More information about the Gcc-bugs
mailing list