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;

Reply via email to