public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Rask Ingemann Lambertsen <rask@sygehus.dk>
To: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] lower-subreg: Decompose multiword shifts
Date: Thu, 02 Aug 2007 18:52:00 -0000	[thread overview]
Message-ID: <20070802185148.GJ25795@sygehus.dk> (raw)
In-Reply-To: <20070802153434.GA24953@blc4eb430604175.ibm.com>

On Thu, Aug 02, 2007 at 05:34:34PM +0200, Andreas Krebbel wrote:
> 
> u64
> foo (u32 high, u32 low)
> {
>   return ((u64)high << 32) | low;
> }
> 
> Although that should be a nop on s390 GCC comes up with:
> 
> foo:
> .LFB2:
>         lr      %r5,%r2
>         lhi     %r4,0
>         sldl    %r4,32
>         or      %r5,%r3
>         lr      %r2,%r4
>         lr      %r3,%r5
>         br      %r14

   Odd, because on ia16, the equivalent multiword shift

u32
foo2 (u16 high, u16 low)
{
  return ((u32)high << 16) | low;
}

produces

foo2:
	pushw	%bp		;# 45	*pushhi1_nonimm
	movw	%sp,	%bp	;# 44	*movhi/1
	movw	6(%bp),	%ax	;# 26	*movhi/1
	movw	4(%bp),	%dx	;# 27	*movhi/1
	popw	%bp		;# 48	*pophi1
	ret			;# 49	*return

which is nearly perfect.

   After the first subreg pass, there is still a shift and two iors:

(note 4 3 9 2 NOTE_INSN_FUNCTION_BEG)

(insn 9 4 37 2 shifttest-lower.c:13 (clobber (reg:HI 32)) -1 (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (nil)))

(insn 37 9 7 2 shifttest-lower.c:13 (clobber (reg:HI 33 [+2 ])) -1 (nil))

(insn 7 37 8 2 shifttest-lower.c:13 (set (reg:HI 32)
        (reg/v:HI 22 [ low ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (nil)))

(insn 8 7 12 2 shifttest-lower.c:13 (set (reg:HI 33 [+2 ])
        (const_int 0 [0x0])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (expr_list:REG_NO_CONFLICT (reg/v:HI 22 [ low ])
            (nil))))

(insn 12 8 38 2 shifttest-lower.c:13 (clobber (reg:HI 34)) -1 (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (nil)))

(insn 38 12 10 2 shifttest-lower.c:13 (clobber (reg:HI 35 [+2 ])) -1 (nil))

(insn 10 38 11 2 shifttest-lower.c:13 (set (reg:HI 34)
        (reg/v:HI 21 [ high ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (nil)))

(insn 11 10 13 2 shifttest-lower.c:13 (set (reg:HI 35 [+2 ])
        (const_int 0 [0x0])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (expr_list:REG_NO_CONFLICT (reg/v:HI 21 [ high ])
            (nil))))

(insn 13 11 16 2 shifttest-lower.c:13 (set (reg:QI 27)
        (const_int 0 [0x0])) 8 {*movqi} (nil))

(insn 16 13 39 2 shifttest-lower.c:13 (clobber (reg:HI 36)) -1 (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (nil)))

(insn 39 16 14 2 shifttest-lower.c:13 (clobber (reg:HI 37 [+2 ])) -1 (nil))

(insn 14 39 15 2 shifttest-lower.c:13 (parallel [
            (set (reg:HI 37 [+2 ])
                (ashift:HI (reg:HI 34)
                    (reg:QI 27)))
            (clobber (reg:CC 13 cc))
        ]) 331 {*ashlhi3} (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (expr_list:REG_EQUAL (ashift:HI (reg:HI 34)
                (const_int 0 [0x0]))
            (nil))))

(insn 15 14 19 2 shifttest-lower.c:13 (set (reg:HI 36)
        (const_int 0 [0x0])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (nil)))

(insn 19 15 40 2 shifttest-lower.c:13 (clobber (reg:HI 30)) -1 (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 40 19 17 2 shifttest-lower.c:13 (clobber (reg:HI 31 [+2 ])) -1 (nil))

(insn 17 40 18 2 shifttest-lower.c:13 (parallel [
            (set (reg:HI 30)
                (ior:HI (reg:HI 32)
                    (reg:HI 36)))
            (clobber (reg:CC 13 cc))
        ]) 75 {*iorhi3} (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 18 17 22 2 shifttest-lower.c:13 (parallel [
            (set (reg:HI 31 [+2 ])
                (ior:HI (reg:HI 33 [+2 ])
                    (reg:HI 37 [+2 ])))
            (clobber (reg:CC 13 cc))
        ]) 75 {*iorhi3} (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 22 18 41 2 shifttest-lower.c:13 (clobber (reg:HI 28 [ <result> ])) -1 (nil))

(insn 41 22 20 2 shifttest-lower.c:13 (clobber (reg:HI 29 [ <result>+2 ])) -1 (nil))

(insn 20 41 21 2 shifttest-lower.c:13 (set (reg:HI 28 [ <result> ])
        (reg:HI 30)) 6 {*movhi} (nil))

(insn 21 20 26 2 shifttest-lower.c:13 (set (reg:HI 29 [ <result>+2 ])
        (reg:HI 31 [+2 ])) 6 {*movhi} (nil))

(insn 26 21 27 2 shifttest-lower.c:15 (set (reg:HI 2 a)
        (reg:HI 28 [ <result> ])) 6 {*movhi} (nil))

(insn 27 26 33 2 shifttest-lower.c:15 (set (reg:HI 4 d [+2 ])
        (reg:HI 29 [ <result>+2 ])) 6 {*movhi} (nil))

(insn 33 27 0 2 shifttest-lower.c:15 (use (reg/i:SI 2 a)) -1 (nil))


   The shift and iors are gone already at cse1:

(note 4 3 9 2 NOTE_INSN_FUNCTION_BEG)

(insn 9 4 7 2 shifttest-lower.c:13 (clobber (reg:HI 32 [ low ])) -1 (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (nil)))

(insn 7 9 8 2 shifttest-lower.c:13 (set (reg:HI 32 [ low ])
        (reg/v:HI 22 [ low ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (nil)))

(insn 8 7 12 2 shifttest-lower.c:13 (set (reg:HI 33 [+2 ])
        (const_int 0 [0x0])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (expr_list:REG_NO_CONFLICT (reg/v:HI 22 [ low ])
            (nil))))

(insn 12 8 10 2 shifttest-lower.c:13 (clobber (reg:HI 34 [ high ])) -1 (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (nil)))

(insn 10 12 11 2 shifttest-lower.c:13 (set (reg:HI 34 [ high ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (nil)))

(insn 11 10 13 2 shifttest-lower.c:13 (set (reg:HI 35 [+2 ])
        (reg:HI 33 [+2 ])) 6 {*movhi} (expr_list:REG_EQUAL (const_int 0 [0x0])
        (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
            (expr_list:REG_NO_CONFLICT (reg/v:HI 21 [ high ])
                (nil)))))

(insn 13 11 16 2 shifttest-lower.c:13 (set (reg:QI 27)
        (subreg:QI (reg:HI 33 [+2 ]) 0)) 8 {*movqi} (expr_list:REG_EQUAL (const_int 0 [0x0])
        (nil)))

(insn 16 13 14 2 shifttest-lower.c:13 (clobber (reg:HI 36)) -1 (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (nil)))

(insn 14 16 15 2 shifttest-lower.c:13 (set (reg:HI 37 [+2 ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (expr_list:REG_EQUAL (reg/v:HI 21 [ high ])
            (nil))))

(insn 15 14 19 2 shifttest-lower.c:13 (set (reg:HI 36)
        (reg:HI 33 [+2 ])) 6 {*movhi} (expr_list:REG_EQUAL (const_int 0 [0x0])
        (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
            (nil))))

(insn 19 15 17 2 shifttest-lower.c:13 (clobber (reg:HI 30)) -1 (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 17 19 18 2 shifttest-lower.c:13 (set (reg:HI 30)
        (reg/v:HI 22 [ low ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 18 17 20 2 shifttest-lower.c:13 (set (reg:HI 31 [+2 ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 20 18 21 2 shifttest-lower.c:13 (set (reg:HI 28 [ <result> ])
        (reg/v:HI 22 [ low ])) 6 {*movhi} (nil))

(insn 21 20 26 2 shifttest-lower.c:13 (set (reg:HI 29 [ <result>+2 ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (nil))

(insn 26 21 27 2 shifttest-lower.c:15 (set (reg:HI 2 a [ <result> ])
        (reg/v:HI 22 [ low ])) 6 {*movhi} (nil))

(insn 27 26 33 2 shifttest-lower.c:15 (set (reg:HI 4 d [+2 ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (nil))

(insn 33 27 0 2 shifttest-lower.c:15 (use (reg/i:SI 2 a)) -1 (nil))


   After fwprop1, only this is left:

(note 4 3 9 2 NOTE_INSN_FUNCTION_BEG)

(insn 9 4 12 2 shifttest-lower.c:13 (clobber (reg:HI 32 [ low ])) -1 (expr_list:REG_LIBCALL_ID (const_int 3 [0x3])
        (nil)))

(insn 12 9 16 2 shifttest-lower.c:13 (clobber (reg:HI 34 [ high ])) -1 (expr_list:REG_LIBCALL_ID (const_int 4 [0x4])
        (nil)))

(insn 16 12 19 2 shifttest-lower.c:13 (clobber (reg:HI 36)) -1 (expr_list:REG_LIBCALL_ID (const_int 5 [0x5])
        (nil)))

(insn 19 16 26 2 shifttest-lower.c:13 (clobber (reg:HI 30)) -1 (expr_list:REG_LIBCALL_ID (const_int 6 [0x6])
        (nil)))

(insn 26 19 27 2 shifttest-lower.c:15 (set (reg:HI 2 a [ <result> ])
        (reg/v:HI 22 [ low ])) 6 {*movhi} (nil))

(insn 27 26 33 2 shifttest-lower.c:15 (set (reg:HI 4 d [+2 ])
        (reg/v:HI 21 [ high ])) 6 {*movhi} (nil))

(insn 33 27 0 2 shifttest-lower.c:15 (use (reg/i:SI 2 a)) -1 (nil))


   Why isn't the same magic happening on s390?

> Index: gcc/testsuite/gcc.dg/multiword-shifts.c
> ===================================================================
> *** /dev/null	1970-01-01 00:00:00.000000000 +0000
> --- gcc/testsuite/gcc.dg/multiword-shifts.c	2007-08-02 11:48:02.000000000 +0200
> ***************
> *** 0 ****
> --- 1,40 ----
> + /* { dg-do run } */
> + /* { dg-options "-O3" } */
> + 
> + typedef unsigned int u32;
> + typedef unsigned long long u64;

   Please use uint32_t and uint64_t from stdint.h (or some other reliable
means of getting types of the sizes you want).

-- 
Rask Ingemann Lambertsen

  parent reply	other threads:[~2007-08-02 18:52 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-02 15:35 Andreas Krebbel
2007-08-02 16:56 ` Paolo Bonzini
2007-08-03 16:41   ` Andreas Krebbel
2007-08-03 19:02     ` Paolo Bonzini
2007-08-02 18:52 ` Rask Ingemann Lambertsen [this message]
2007-08-02 19:21   ` Andreas Krebbel
2007-08-07  1:41     ` Rask Ingemann Lambertsen
2007-08-07  8:29       ` Andreas Krebbel
2007-08-02 23:16 ` Rask Ingemann Lambertsen
2007-08-03 12:03   ` Michael Matz
2007-08-03 14:34   ` Andreas Krebbel
2007-08-03 15:37     ` Michael Matz
2007-08-07  1:08       ` Ian Lance Taylor
2007-08-07  1:27 ` Ian Lance Taylor
2007-08-07 10:47   ` Andreas Krebbel
2007-08-08 18:40     ` Andreas Tobler
2007-08-09  7:45       ` Andreas Krebbel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070802185148.GJ25795@sygehus.dk \
    --to=rask@sygehus.dk \
    --cc=Andreas.Krebbel@de.ibm.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).