On 03/25/2011 05:41 AM, Georg-Johann Lay wrote:
>> On 03/22/2011 06:48 PM, Richard Henderson wrote:
>>
>>> Ok. Watch out for other target problems this week.
>
> libgcc fails to build for avr (SVN 171446)
>
> ../../../../../gcc.gnu.org/trunk/libgcc/../gcc/libgcc2.c: In function
> '__negdi2':
> ../../../../../gcc.gnu.org/trunk/libgcc/../gcc/libgcc2.c:68:17:
> internal compiler error: in maybe_gen_insn, at optabs.c:7123
This is due to a miscommunication between the middle-end and the backend
about how many arguments the setmemhi pattern takes.
(define_expand "setmemhi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(match_operand 2 "const_int_operand" ""))
(use (match_operand:HI 1 "const_int_operand" ""))
(use (match_operand:HI 3 "const_int_operand" "n"))
(clobber (match_scratch:HI 4 ""))
(clobber (match_dup 5))])]
The match_scratch is counted in .n_operands, which makes the count of
operands not equal 4, so we assume 6 operands are necessary. We can
fix this for the special case of avr by only assuming 6 operands when
there are in fact 6 operands, but of course this could fail just as
easily if there were two scratches.
All of which suggests that optional arguments to a named optab is a
mistake that ought to be rectified.
I plan to commit the following after bootstrap and check.
r~
diff --git a/gcc/expr.c b/gcc/expr.c
index 4db1c77..0a95aa7 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1299,11 +1299,10 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size,
unsigned int align,
/* The check above guarantees that this size conversion is valid. */
create_convert_operand_to (&ops[2], size, mode, true);
create_integer_operand (&ops[3], align / BITS_PER_UNIT);
- if (nops != 4)
+ if (nops == 6)
{
create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
create_integer_operand (&ops[5], expected_size);
- nops = 6;
}
if (maybe_expand_insn (code, nops, ops))
{
@@ -2721,11 +2720,10 @@ set_storage_via_setmem (rtx object, rtx size, rtx val,
unsigned int align,
create_convert_operand_to (&ops[1], size, mode, true);
create_convert_operand_from (&ops[2], val, byte_mode, true);
create_integer_operand (&ops[3], align / BITS_PER_UNIT);
- if (nops != 4)
+ if (nops == 6)
{
create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
create_integer_operand (&ops[5], expected_size);
- nops = 6;
}
if (maybe_expand_insn (code, nops, ops))
return true;