RTL problem with optimizations
Petar Penchev
ptr@melexis.com
Wed Sep 15 12:51:00 GMT 2004
Hello All,
I have defined RTL patterns for HImode in my .md files as follows :
(define_expand "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "")
(ashift:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "general_operand" "")))]
""
"
{
/* If the argument is not a const, load it in a register */
if (GET_CODE (operands[2]) != CONST_INT)
{
emit_insn (gen_rtx (PARALLEL, VOIDmode,
gen_rtvec (2, gen_rtx (SET, VOIDmode,
operand0,
gen_rtx_ASHIFT (HImode,
operand1, operand2)),
gen_rtx (CLOBBER, VOIDmode, operand2))));
DONE;
}
}")
(define_insn "*ashlhi3_reg"
[(parallel
[
(set (match_operand:HI 0 "register_operand" "=b,x")
(ashift:HI (match_operand:HI 1 "register_operand" "%0,0")
(match_operand:HI 2 "register_operand" "x,b")
)
)
(clobber (match_dup 2))
]
)]
""
{
mlx16_emit_shift( HImode, (which_alternative == 0), ASHIFT, operands );
return "";
}
[(set_attr "cc" "set_zn,set_zn")]
)
This pattern works, unless I try to compile newlib's file hash.c with -O3
option specified.
GCC gives followintg error :
->>>
../../../../../newlib_src/newlib/libc/search/hash.c:957: error:
unrecognizable insn:
(insn 102 101 104 6
../../../../../newlib_src/newlib/libc/search/hash.c:955 (par
allel [
(set (reg:HI 49)
(ashift:HI (reg/v:HI 18 [ i ])
(reg:HI 48 [ <variable>.hdr.sshift ])))
(clobber (reg:HI 74 [ <variable>.hdr.sshift ]))
]) -1 (insn_list 101 (nil))
(expr_list:REG_DEAD (reg:HI 48 [ <variable>.hdr.sshift ])
(expr_list:REG_UNUSED (reg:HI 74 [ <variable>.hdr.sshift ])
(expr_list:REG_EQUAL (ashift:HI (reg/v:HI 18 [ i ])
(reg/v:HI 69 [ <variable>.hdr.sshift ]))
(nil)))))
../../../../../newlib_src/newlib/libc/search/hash.c:957: internal compiler
error
: in extract_insn, at recog.c:2083
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
->>>
When I look at RTL dumps , I see :
hash.c.16.loop2:
(insn 102 101 104 6
../../../../../newlib_src/newlib/libc/search/hash.c:955 (parallel [
(set (reg:HI 49)
(ashift:HI (reg/v:HI 18 [ i ])
(reg:HI 48 [ <variable>.hdr.sshift ])))
(clobber (reg:HI 48 [ <variable>.hdr.sshift ]))
]) -1 (nil)
(expr_list:REG_EQUAL (ashift:HI (reg/v:HI 18 [ i ])
(reg/v:HI 69 [ <variable>.hdr.sshift ]))
(nil)))
This perfectly match to my desription in the RTL file.
However if I take a look into hash.c.17.web
(insn 102 101 104 6
../../../../../newlib_src/newlib/libc/search/hash.c:955 (parallel [
(set (reg:HI 49)
(ashift:HI (reg/v:HI 18 [ i ])
(reg:HI 48 [ <variable>.hdr.sshift ])))
(clobber (reg:HI 74 [ <variable>.hdr.sshift ]))
]) -1 (nil)
(expr_list:REG_EQUAL (ashift:HI (reg/v:HI 18 [ i ])
(reg/v:HI 69 [ <variable>.hdr.sshift ]))
(nil)))
I tried to find something about .web but I couldn't. I am wondering why
gcc replaces reg 48 with reg 75 and if there is a way to
explain it not to do that :). Of course I can define pattern to match such
instruction, but this seems to me to be wrong.
I have the same problem with -O4 optimizations. This problem does not
appear with other -Ox options.
GCCINT does not say anything about .web, i.e. after which compilation
phase it is being generated.
My questions are about this .web file , what it is ? and why compiler
decides to replace clobber register ?
Regards
--
Petar Penchev
Software engineer
More information about the Gcc
mailing list