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.