[PATCH][Combine] missed one ASHIFTRT opt opportunity

Jiong Wang jiong.wang@arm.com
Tue Jul 29 17:30:00 GMT 2014


Suppose the following shift:

T A = (T) B  << C

which met the following conditions:
* T is a signed type with 2 x word_size.
* B is with signed type with the size <= word_size.
* C + sizeof (B) < word_size.

|<           T          >|
|   high     |   low     |
      | B shifted to |
      |   E   |   D  |

gcc is generating sub-optimal instruction pattern for most targets, like arm/mips/sparc, during rtl expand.

gcc's expand logic is:

1. assign low with B.
2. assign high with sign bit of B spreaded.
3. logic left shift low by C bit to get the final low.
4. logic left shift high by E bit.
5. logic right shift B by D bit.
6. or the result of 4 and 5 to get final high.

step 2, 4, 5, 6 could actually be combined into one step: arithmetic right shift B by D bit.

aarch64 example
================
what gcc generate for

__int128_t
load3 (int data)
{
   return (__int128_t) data << 50;
}

==>
         sxtw    x2, w0
         asr     x1, x2, 63
         lsl     x0, x2, 50
         lsl     x1, x1, 50
         orr     x1, x1, x2, lsr 14

actually could be simplified to
         sxtw    x1, w0
         lsl     x0, x1, 50
         asr     x1, x1, 14

the following three instructions are actually doing "asr     x1, x1, 14"
         asr     x1, x2, 63
         lsl     x1, x1, 50
         orr     x1, x1, x2, lsr 14

arm example (.fpu softvfp)
===========

what gcc generated for

long long
shift (int data)
{
   return (long long) data << 20;
}

==>
shift:
         stmfd   sp!, {r4, r5}
         mov     r5, r0, asr #31
         mov     r3, r0
         mov     r0, r0, asl #20
         mov     r1, r5, asl #20
         orr     r1, r1, r3, lsr #12
         ldmfd   sp!, {r4, r5}
         bx      lr

actually could be simplified to
shift:
         mov     r1, r0
         mov     r0, r0, asl #20
         mov     r1, r1, asr #12
         bx      lr

this patch tring to combine step 2, 4, 5, 6 into one single arithmetic
right shift in gcc's combine pass.


test done
===
bootstrap OK on x86-64/aarch64
no regresson aarch64-none-elf/arm-none-eabi
  
please review, thanks.

-- Jiong

gcc/
   * simplify-rtx.c (simplify_binary_operation_1): New combine check for ASHIFTRT.

gcc/testsuite
   * gcc.dg/wide_shift_64_1.c: New testcase.
   * gcc.dg/wide_shift_128_1.c: Ditto.
   * gcc.target/aarch64/ashlti3_1.c: Ditto.
   * gcc.target/arm/ashldisi_1.c: Ditto.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: opt-ashiftrt.patch
Type: text/x-patch
Size: 8130 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20140729/74ad2906/attachment.bin>


More information about the Gcc-patches mailing list