This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
BUG x86 define_expand "strlensi"
- To: gcc at gcc dot gnu dot org
- Subject: BUG x86 define_expand "strlensi"
- From: grahams <grahams at rcp dot co dot uk>
- Date: Mon, 07 Feb 2000 20:16:20 +0000
All
I have been investigating problems with the define_expand "strlensi"
pattern on the x86 and have come to the conclusion that it cannot
use FAIL (i.e. it must expand or abort).
There are two reasons for coming to this conclusion
1.) The expand_builtin_strlen () in builtins.c calls the MD
backend expander (i.e. gen_strlensi) using the following
emit_insn (GEN_FCN (icode)(result, ...);
If the MD gen_strlensi expander uses FAIL (can't expand) then
a NULL_RTX is returned and it make no sense to call emit_insn
with a NULL_RTX
2.) Assuming the gen_strlensi () expander is correct in using
FAIL then the above code would need to be written
expanded_rtx = GEN_FCN (icode)(result, ...);
if (!expanded_rtx)
return NULL_RTX;
emit_insn (expanded_rtx);
But this in itself can causes aborts in expand_expr ()
if the rtl being expanded has a RTL_EXPR with a non-zero
RTL_EXPR_SEQUENCE ().
The abort occurs because the when expand_expr processes a RTL_EXPR
with a non-zero RTL_EXPR_SEQUENCE() it finds it's value is const0_rtx.
Note that when expand_expr processing a RTL_EXPR with a non zero
RTL_EXPR_SEQUENCE() has the side effect of setting the RTL_EXPR_SEQUENCE ()
to const0_rtx.
I found that RTL_EXPR node was being expanded twice the 1st time via a
call to expand_expr() in expand_builtin_strlen() and subsequently if the
MD expander bailed out using FAIL a call to expand_expr() in expand_call().
This is an extract from i386.md file which shows its use of FAIL.
(define_expand "strlensi" [(set (match_operand:SI 0 "register_operand" "")
(unspec:SI [(match_operand:BLK 1 "general_operand" "")
(match_operand:QI 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")] 0))] ""
"
{
rtx out, addr, eoschar, align, scratch1, scratch2, scratch3;
/* The generic case of strlen expander is long. Avoid it's
expanding unless TARGET_INLINE_ALL_STRINGOPS. */
if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
&& !optimize_size
&& (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
FAIL;
This code is using eoschar and align before they are initialized (
reported this in a separate mailing to gcc-bugs a couple of days ago)
I don't understand how the comment matches the actual test performed?
I think this test should be deleted so that the expander always
returns using DONE.
Comments anyone?
Graham