[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:293fabe638769ee862ce2aa1008497fc870da2a7 commit 293fabe638769ee862ce2aa1008497fc870da2a7 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:327a4cf5c54d726996c43ae9748bcbc277409859 commit 327a4cf5c54d726996c43ae9748bcbc277409859 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:808a9f717fc195dbc3db1bf2b88d2f6993ee5132 commit 808a9f717fc195dbc3db1bf2b88d2f6993ee5132 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:b71e434c5689697d4204c7b145592bb66ab99c75 commit b71e434c5689697d4204c7b145592bb66ab99c75 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:eb95676c8fccd753acec8cc0445e350ff2aad39d commit eb95676c8fccd753acec8cc0445e350ff2aad39d Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:1d00b2993352ae98975ce7044d6ae689ef2b98b6 commit 1d00b2993352ae98975ce7044d6ae689ef2b98b6 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:e601fc5fc352cdd28c2f08d44233ba3a474ce1ee commit e601fc5fc352cdd28c2f08d44233ba3a474ce1ee Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:de1cd618583a653d3d48b50efbe90c619f77b6c3 commit de1cd618583a653d3d48b50efbe90c619f77b6c3 Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:9a12ab921604d63d2978b7bb2792ca4ed8337c6b commit 9a12ab921604d63d2978b7bb2792ca4ed8337c6b Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:eda6b3ed5932aeb72d206db947bb45133217ea4d commit eda6b3ed5932aeb72d206db947bb45133217ea4d Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid multiple assignments to output object
https://gcc.gnu.org/g:7f8c70a00f2cbf6bd19566e8b0977ec14b51cb3a commit 7f8c70a00f2cbf6bd19566e8b0977ec14b51cb3a Author: Jeff Law Date: Mon May 19 20:31:27 2025 -0600 [RISC-V] Avoid multiple assignments to output object This is the next batch of changes to reduce multiple assignments to an output object. This time I'm focused on splitters in bitmanip.md. This doesn't convert every case. For example there is one case that is very clearly dependent on eliminating mvconst_internal and adjustment of a splitter for andn and until those things happen it would clearly be a QOI implementation regression. There are cases where we set a scratch register more than once. It may be possible to use an additional scratch. I haven't tried that yet. I've seen one failure to if-convert a sequence after this patch, but it should be resolved once the logical AND changes are merged. Otherwise I'm primarily seeing slight differences in register allocation and scheduling. Nothing concerning to me. This has run through my tester, but I obviously want to see how it behaves in the upstream CI system as that tests slightly different multilibs than mine (on purpose). gcc/ * config/riscv/bitmanip.md (various splits): Avoid writing the output more than once when trivially possible. (cherry picked from commit 9de7d374323eea212aa1ffb2208a0c7cfcf46f51) Diff: --- gcc/config/riscv/bitmanip.md | 89 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7e6f3df51335..85ace285ff0a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -1,4 +1,4 @@ -;; Machine description for RISC-V Bit Manipulation operations. +;); Machine description for RISC-V Bit Manipulation operations. ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -68,23 +68,25 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) (match_operand:QI 2 "imm123_operand")) -(subreg:SI (match_operand:DI 3 "register_operand") 0] +(subreg:SI (match_operand:DI 3 "register_operand") 0 + (clobber (match_operand:DI 4 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 4) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 4) 0)))]) (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "imm123_operand")) (match_operand:DI 3 "consecutive_bits_operand")) 0) -(subreg:SI (match_operand:DI 4 "register_operand") 0] +(subreg:SI (match_operand:DI 4 "register_operand") 0 + (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3])) /* Ensure the mask includes all the bits in SImode. */ && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)" - [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) - (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))]) + [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4))) + (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 5) 0)))]) ; Make sure that an andi followed by a sh[123]add remains a two instruction ; sequence--and is not torn apart into slli, slri, add. @@ -195,13 +197,14 @@ (match_operand:QI 2 "imm123_operand")) (match_operand 3 "consecutive_bits32_operand")) (match_operand:DI 4 "register_operand")) -(match_operand 5 "immediate_operand")))] +(match_operand 5 "immediate_operand"))) + (clobber (match_operand:DI 6 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" - [(set (match_dup 0) + [(set (match_dup 6) (plus:DI (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)) (match_dup 4))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 5)))]) + (set (match_dup 0) (plus:DI (match_dup 6) (match_dup 5)))]) ;; ZBB e
