Looks good too. Please proceed with your commit.

Thank you for your contribution,
//Claudiu

-----Original Message-----
From: Roger Sayle <ro...@nextmovesoftware.com> 
Sent: Monday, November 6, 2023 7:30 PM
To: gcc-patches@gcc.gnu.org
Cc: 'Claudiu Zissulescu' <claz...@gmail.com>
Subject: [ARC PATCH] Improved DImode rotates and right shifts by one bit.


This patch improves the code generated for DImode right shifts (both arithmetic 
and logical) by a single bit, and also for DImode rotates (both left and right) 
by a single bit.  In approach, this is similar to the recently added DImode 
left shift by a single bit patch, but also builds upon i386.md's UNSPEC carry 
flag representation:
https://urldefense.com/v3/__https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632169.html__;!!A4F2R9G_pg!fxasivX0MLFBbgzab_TjnY9wQnIao29buOVHUv6gvPzOS-W4IWfIdwse4TRg__ek2AEplJ7BpYrTYBt1hB8mUCM$
 

The benefits can be seen from the four new test cases:

long long ashr(long long x) { return x >> 1; }

Before:
ashr:   asl     r2,r1,31
        lsr_s   r0,r0
        or_s    r0,r0,r2
        j_s.d   [blink]
        asr_s   r1,r1,1

After:
ashr:   asr.f   r1,r1
        j_s.d   [blink]
        rrc     r0,r0

unsigned long long lshr(unsigned long long x) { return x >> 1; }

Before:
lshr:   asl     r2,r1,31
        lsr_s   r0,r0
        or_s    r0,r0,r2
        j_s.d   [blink]
        lsr_s   r1,r1

After:
lshr:   lsr.f   r1,r1
        j_s.d   [blink]
        rrc     r0,r0

unsigned long long rotl(unsigned long long x) { return (x<<1) | (x>>63); }

Before:
rotl:   lsr     r12,r1,31
        lsr     r2,r0,31
        asl_s   r3,r0,1
        asl_s   r1,r1,1
        or      r0,r12,r3
        j_s.d   [blink]
        or_s    r1,r1,r2

After:
rotl:   add.f   r0,r0,r0
        adc.f   r1,r1,r1
        j_s.d   [blink]
        add.cs  r0,r0,1

unsigned long long rotr(unsigned long long x) { return (x>>1) | (x<<63); }

Before:
rotr:   asl     r12,r1,31
        asl     r2,r0,31
        lsr_s   r3,r0
        lsr_s   r1,r1
        or      r0,r12,r3
        j_s.d   [blink]
        or_s    r1,r1,r2

After:
rotr:   asr.f   0,r0
        rrc.f   r1,r1
        j_s.d   [blink]
        rrc     r0,r0

On CPUs without a barrel shifter the improvements are even better.

Tested with a cross-compiler to arc-linux hosted on x86_64, with no new 
(compile-only) regressions from make -k check.
Ok for mainline if this passes Claudiu's nightly testing?


2023-11-06  Roger Sayle  <ro...@nextmovesoftware.com>

gcc/ChangeLog
        * config/arc/arc.md (UNSPEC_ARC_CC_NEZ): New UNSPEC that
        represents the carry flag being set if the operand is non-zero.
        (adc_f): New define_insn representing adc with updated flags.
        (ashrdi3): New define_expand that only handles shifts by 1.
        (ashrdi3_cnt1): New pre-reload define_insn_and_split.
        (lshrdi3): New define_expand that only handles shifts by 1.
        (lshrdi3_cnt1): New pre-reload define_insn_and_split.
        (rrcsi2): New define_insn for rrc (SImode rotate right through carry).
        (rrcsi2_carry): Likewise for rrc.f, as above but updating flags.
        (rotldi3): New define_expand that only handles rotates by 1.
        (rotldi3_cnt1): New pre-reload define_insn_and_split.
        (rotrdi3): New define_expand that only handles rotates by 1.
        (rotrdi3_cnt1): New pre-reload define_insn_and_split.
        (lshrsi3_cnt1_carry): New define_insn for lsr.f.
        (ashrsi3_cnt1_carry): New define_insn for asr.f.
        (btst_0_carry): New define_insn for asr.f without result.

gcc/testsuite/ChangeLog
        * gcc.target/arc/ashrdi3-1.c: New test case.
        * gcc.target/arc/lshrdi3-1.c: Likewise.
        * gcc.target/arc/rotldi3-1.c: Likewise.
        * gcc.target/arc/rotrdi3-1.c: Likewise.


Thanks in advance,
Roger
--

Reply via email to