https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120983

            Bug ID: 120983
           Summary: recog violates earlyclobber with user-defined hard
                    register before reload (causing ICE on
                    gcc.target/loongarch/bitwise-shift-reassoc-clobber.c)
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xry111 at gcc dot gnu.org
  Target Milestone: ---

bitwise-shift-reassoc-clobber.c:12:1: error: unable to generate reloads for
impossible constraints:
   12 | }
      | ^
(insn 12 10 15 2 (set (reg/v:DI 23 $r23 [ x ])
        (sign_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (reg/v:DI 23
$r23 [ x ])
                            (const_int 3 [0x3]))
                        (const_int 2208 [0x8a0])) 0)
                (reg:SI 23 $r23 [ x ]))))
"bitwise-shift-reassoc-clobber.c":11:7 272 {and_alsl_reversesi_extended}
     (nil))

During combine we get:

Trying 10 -> 12:
   10: r91:DI=sign_extend($r23:DI<<0x3&0x8a0#0+$r23:SI)
      REG_DEAD $r23:DI
   12: $r23:DI=r91:DI
      REG_DEAD r91:DI
Successfully matched this instruction:
(set (reg/v:DI 23 $r23 [ x ])
    (sign_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (reg/v:DI 23 $r23 [
x ])
                        (const_int 3 [0x3]))
                    (const_int 2208 [0x8a0])) 0)
            (reg:SI 23 $r23 [ x ]))))
allowing combination of insns 10 and 12

which violates the earlyclobber in <optab>_alsl_reversesi_extended:

  [(set (match_operand:DI 0 "register_operand" "=&r")
        (sign_extend:DI
          (plus:SI
            (subreg:SI
              (any_bitwise:DI
                (ashift:DI
                  (match_operand:DI 1 "register_operand" "r0")
                  (match_operand:SI 2 "const_immalsl_operand" ""))
                (match_operand:DI 3 "const_int_operand" "i"))
              0)
            (match_operand:SI 4 "register_operand" "r"))))]

The combine maintainer suggests either this is a user error, or an issue in the
machine description, or recog is doing things wrong.

I cannot believe this should be considered a user error: the user cannot
anticipate what the RTL optimization passes will do to his/her defined hard
register variable.  Thus if we consider this a user error, the user-defined
hard register variables would be unusable at all.  (If this was an inline-asm
we can claim it as a user error though.)

I also don't think we'd consider this something wrong in the machine
description.  Yes we can do things like
https://gcc.gnu.org/pipermail/gcc-patches/2025-July/688634.html for this
specific insn, but how about all other insns using an earlyclobber?  There are
about 1200 matches of [+=]& in *.md, would it be really rational to audit them
one by one???

Thus to me either recog should just reject this, or reload should "work this
around" like what happend before GCC 9.

Reply via email to