https://gcc.gnu.org/g:b433140a6cb40acedb2e6cb43c4e5a388e33f805
commit r15-5074-gb433140a6cb40acedb2e6cb43c4e5a388e33f805 Author: Takayuki 'January June' Suwa <jjsuwa_sys3...@yahoo.co.jp> Date: Sun Nov 10 15:39:22 2024 +0900 xtensa: Fix the issue in "*extzvsi-1bit_addsubx" The second source register of insn "*extzvsi-1bit_addsubx" cannot be the same as the destination register, because that register will be overwritten with an intermediate value after insn splitting. /* example #1 */ int test1(int b, int a) { return ((a & 1024) ? 4 : 0) + b; } ;; result #1 (incorrect) test1: extui a2, a3, 10, 1 ;; overwrites A2 before used addx4 a2, a2, a2 ret.n This patch fixes that. ;; result #1 (correct) test1: extui a3, a3, 10, 1 ;; uses A3 and then overwrites addx4 a2, a3, a2 ret.n However, it should be noted that the first source register can be the same as the destination without any problems. /* example #2 */ int test2(int a, int b) { return ((a & 1024) ? 4 : 0) + b; } ;; result (correct) test2: extui a2, a2, 10, 1 ;; uses A2 and then overwrites addx4 a2, a2, a3 ret.n gcc/ChangeLog: * config/xtensa/xtensa.md (*extzvsi-1bit_addsubx): Add '&' to the destination register constraint to indicate that it is 'earlyclobber', append '0' to the first source register constraint to indicate that it can be the same as the destination register, and change the split condition from 1 to reload_completed so that the insn will be split only after RA in order to obtain allocated registers that satisfy the above constraints. Diff: --- gcc/config/xtensa/xtensa.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 2c08c7d6bf10..cecd319685c0 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -1109,17 +1109,17 @@ (const_int 6)))]) (define_insn_and_split "*extzvsi-1bit_addsubx" - [(set (match_operand:SI 0 "register_operand" "=a") + [(set (match_operand:SI 0 "register_operand" "=&a") (match_operator:SI 5 "addsub_operator" [(and:SI (match_operator:SI 6 "logical_shift_operator" - [(match_operand:SI 1 "register_operand" "r") + [(match_operand:SI 1 "register_operand" "r0") (match_operand:SI 3 "const_int_operand" "i")]) (match_operand:SI 4 "const_int_operand" "i")) (match_operand:SI 2 "register_operand" "r")]))] "TARGET_ADDX && IN_RANGE (exact_log2 (INTVAL (operands[4])), 1, 3)" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (zero_extract:SI (match_dup 1) (const_int 1)