https://gcc.gnu.org/g:e2bbe8eb23cb1d2e9b98725339e2ead46170123e
commit r15-11682-ge2bbe8eb23cb1d2e9b98725339e2ead46170123e Author: Richard Earnshaw <[email protected]> Date: Mon Oct 5 17:00:08 2026 +0100 aarch64: Fix more cases of gen_highpart on subregs [PR127393] Following on from the fix in r17-4565, there were reports of more cases where we could get ICEs during expansion of TImode patterns when subregs were in use. I've now gone through the machine description file and hopefully identified the remaining cases where this could be a problem. gcc/ChangeLog: PR target/127393 * config/aarch64/aarch64.md (movti): Ensure we don't call gen_highpart on a subreg. (addti3): Use pure_register_operand for the destination. (addvti4): Likewise. (uaddvti4): Likewise. (subti3): Likewise. (subvti4): Likewise. (usubti4): Likewise. (<su_optab>mulditi3): Likewise. (multi3): Require pure_register_operand for all operands. (cherry picked from commit a947f841925f5e65c4c47711c995ae4094a20ea4) Diff: --- gcc/config/aarch64/aarch64.md | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 27702111262b..377d385d28cd 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1742,18 +1742,27 @@ [(set (match_operand:TI 0 "nonimmediate_operand") (match_operand:TI 1 "general_operand"))] "" - " + { if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) operands[1] = force_reg (TImode, operands[1]); if (GET_CODE (operands[1]) == CONST_POLY_INT) { - emit_move_insn (gen_lowpart (DImode, operands[0]), + rtx op0 = operands[0]; + /* It's not generally safe to use gen_highpart on a SUBREG, so + write the initial result to a temporary. The optimizer will + simplify things later. */ + if (SUBREG_P (op0)) + op0 = gen_reg_rtx (TImode); + + emit_move_insn (gen_lowpart (DImode, op0), gen_lowpart (DImode, operands[1])); - emit_move_insn (gen_highpart (DImode, operands[0]), const0_rtx); + emit_move_insn (gen_highpart (DImode, op0), const0_rtx); + if (op0 != operands[0]) + emit_move_insn (operands[0], op0); DONE; } - " + } ) (define_insn "*movti_aarch64" @@ -2703,7 +2712,7 @@ }) (define_expand "addti3" - [(set (match_operand:TI 0 "register_operand") + [(set (match_operand:TI 0 "pure_register_operand") (plus:TI (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm")))] "" @@ -2736,7 +2745,7 @@ }) (define_expand "addvti4" - [(match_operand:TI 0 "register_operand") + [(match_operand:TI 0 "pure_register_operand") (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] @@ -2770,7 +2779,7 @@ }) (define_expand "uaddvti4" - [(match_operand:TI 0 "register_operand") + [(match_operand:TI 0 "pure_register_operand") (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] @@ -3478,7 +3487,7 @@ }) (define_expand "subti3" - [(set (match_operand:TI 0 "register_operand") + [(set (match_operand:TI 0 "pure_register_operand") (minus:TI (match_operand:TI 1 "aarch64_reg_or_zero") (match_operand:TI 2 "register_operand")))] "" @@ -3498,7 +3507,7 @@ }) (define_expand "subvti4" - [(match_operand:TI 0 "register_operand") + [(match_operand:TI 0 "pure_register_operand") (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] @@ -3517,7 +3526,7 @@ }) (define_expand "usubvti4" - [(match_operand:TI 0 "register_operand") + [(match_operand:TI 0 "pure_register_operand") (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] @@ -4299,7 +4308,7 @@ ) (define_expand "<su_optab>mulditi3" - [(set (match_operand:TI 0 "register_operand") + [(set (match_operand:TI 0 "pure_register_operand") (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand")) (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))] "" @@ -4318,9 +4327,9 @@ ;; The default expansion of multi3 using umuldi3_highpart will perform ;; the additions in an order that fails to combine into two madd insns. (define_expand "multi3" - [(set (match_operand:TI 0 "register_operand") - (mult:TI (match_operand:TI 1 "register_operand") - (match_operand:TI 2 "register_operand")))] + [(set (match_operand:TI 0 "pure_register_operand") + (mult:TI (match_operand:TI 1 "pure_register_operand") + (match_operand:TI 2 "pure_register_operand")))] "" { rtx l0 = gen_reg_rtx (DImode);
