]> git.ipfire.org Git - thirdparty/gcc.git/commit
arm: [MVE] Fix carry-in support for vadcq / vsbcq [PR122189]
authorChristophe Lyon <christophe.lyon@linaro.org>
Thu, 2 Oct 2025 13:52:22 +0000 (13:52 +0000)
committerChristophe Lyon <christophe.lyon@linaro.org>
Wed, 15 Oct 2025 12:34:33 +0000 (12:34 +0000)
commit027205879733933ec991c230795da6c01ac50029
treeae06f8ad306dd270162700b99c23a09d566be6c5
parentda293ec6b68fab23c44f6643011cf7ae62d93b16
arm: [MVE] Fix carry-in support for vadcq / vsbcq [PR122189]

The vadcq and vsbcq patterns had two problems:
- the adc / sbc part of the pattern did not mention the use of vfpcc
- the carry calcultation part should use a different unspec code

In addtion, the get_fpscr_nzcvqc and set_fpscr_nzcvqc were
over-cautious by using unspec_volatile when unspec is really what they
need.  Making them unspec enables to remove redundant accesses to
FPSCR_nzcvqc.

With unspec_volatile, we used to generate:
test_2:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
vmov.i32 q0, #0x1  @ v4si
push {lr}
sub sp, sp, #12
vmrs r3, FPSCR_nzcvqc    ;; [1]
bic r3, r3, #536870912
vmsr FPSCR_nzcvqc, r3
vadc.i32 q3, q0, q0
vmrs r3, FPSCR_nzcvqc     ;; [2]
vmrs r3, FPSCR_nzcvqc
orr r3, r3, #536870912
vmsr FPSCR_nzcvqc, r3
vadc.i32 q0, q0, q0
vmrs r3, FPSCR_nzcvqc
ldr r0, .L8
ubfx r3, r3, #29, #1
str r3, [sp, #4]
bl print_uint32x4_t
add sp, sp, #12
@ sp needed
pop {pc}
.L9:
.align 2
.L8:
.word .LC1

with unspec, we generate:
test_2:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
vmrs r3, FPSCR_nzcvqc     ;; [1]
bic r3, r3, #536870912   ;; [3]
vmov.i32 q0, #0x1  @ v4si
vmsr FPSCR_nzcvqc, r3
vadc.i32 q3, q0, q0
vmrs r3, FPSCR_nzcvqc
orr r3, r3, #536870912
vmsr FPSCR_nzcvqc, r3
vadc.i32 q0, q0, q0
vmrs r3, FPSCR_nzcvqc
push {lr}
ubfx r3, r3, #29, #1
sub sp, sp, #12
ldr r0, .L8
str r3, [sp, #4]
bl print_uint32x4_t
add sp, sp, #12
@ sp needed
pop {pc}
.L9:
.align 2
.L8:
.word .LC1

That is, unspec in get_fpscr_nzcvqc enables to:
- move [1] earlier
- delete redundant [2]

and unspec in set_fpscr_nzcvqc enables to move push {lr} and stack
manipulation later.

gcc/ChangeLog:

PR target/122189
* config/arm/iterators.md (VxCIQ_carry, VxCIQ_M_carry, VxCQ_carry)
(VxCQ_M_carry): New iterators.
* config/arm/mve.md (get_fpscr_nzcvqc, set_fpscr_nzcvqc): Use
unspec instead of unspec_volatile.
(vadciq, vadciq_m, vadcq, vadcq_m): Use vfpcc in operation.  Use a
different unspec code for carry calcultation.
* config/arm/unspecs.md (VADCQ_U_carry, VADCQ_M_U_carry)
(VADCQ_S_carry, VADCQ_M_S_carry, VSBCIQ_U_carry ,VSBCIQ_S_carry
,VSBCIQ_M_U_carry ,VSBCIQ_M_S_carry ,VSBCQ_U_carry ,VSBCQ_S_carry
,VSBCQ_M_U_carry ,VSBCQ_M_S_carry ,VADCIQ_U_carry
,VADCIQ_M_U_carry ,VADCIQ_S_carry ,VADCIQ_M_S_carry): New unspec
codes.

gcc/testsuite/ChangeLog:

PR target/122189
* gcc.target/arm/mve/intrinsics/vadcq-check-carry.c: New test.
* gcc.target/arm/mve/intrinsics/vadcq_m_s32.c: Adjust instructions
order.
* gcc.target/arm/mve/intrinsics/vadcq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c: Likewise.
gcc/config/arm/iterators.md
gcc/config/arm/mve.md
gcc/config/arm/unspecs.md
gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq-check-carry.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_s32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_u32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c