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

--- Comment #18 from Peter Bergner <bergner at gcc dot gnu.org> ---
(In reply to Xi Ruoyao from comment #13)
> I'm almost sure this is causing
> gcc.target/loongarch/bitwise-shift-reassoc-clobber.c ICE in GCC 16:
> 
> 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))
> 
> 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"))))]

So the error message is coming from this hunk in my patch:

+               /* Both the earlyclobber operand and conflicting operand
+                  cannot both be user defined hard registers.  */
+               if (HARD_REGISTER_P (operand_reg[i])
+                   && REG_USERVAR_P (operand_reg[i])
+                   && operand_reg[j] != NULL_RTX
+                   && HARD_REGISTER_P (operand_reg[j])
+                   && REG_USERVAR_P (operand_reg[j]))
+                 fatal_insn ("unable to generate reloads for "
+                             "impossible constraints:", curr_insn);

...which I believe is correct.  As you said, operand 4 cannot use the same
register as the early clobber output operand 0, and this hunk is catching the
illegal usage.  That is a good thing.

Reply via email to