This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/63321] [SH] Unused T bit result of shll / shlr insns
- From: "olegendo at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 11 Jan 2015 12:10:50 +0000
- Subject: [Bug target/63321] [SH] Unused T bit result of shll / shlr insns
- Auto-submitted: auto-generated
- References: <bug-63321-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63321
--- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> ---
The shll/shlr insns effectively perform two operations:
T = zero_extract single bit 0 / 31 from reg
reg = reg << 1 / reg >> 1.
The other shift insns as in comment #5 perform only a single operation. Thus
those two things should be probably handled slightly differently.
With my current patchset for handling single bit zero_extract (PR 64345), code
like
void test4 (unsigned int x, unsigned int* y)
{
y[0] = (x >> 0) & 1;
y[1] = (x >> 1) & 1;
y[2] = (x >> 2) & 1;
y[3] = (x >> 3) & 1;
}
results in the following insns right after the combine pass:
(insn 7 4 8 2 (set (reg:SI 171 [ D.1733 ])
(and:SI (reg/v:SI 169 [ x ])
(const_int 1 [0x1]))) sh_tmp.cpp:432 115 {*andsi_compact}
(nil))
...
(insn 10 9 11 2 (parallel [
(set (reg:SI 173 [ D.1733 ])
(zero_extract:SI (reg/v:SI 169 [ x ])
(const_int 1 [0x1])
(const_int 1 [0x1])))
(clobber (reg:SI 147 t))
]) sh_tmp.cpp:433 409 {any_treg_expr_to_reg}
(expr_list:REG_UNUSED (reg:SI 147 t)
(nil)))
...
(insn 13 12 14 2 (parallel [
(set (reg:SI 175 [ D.1733 ])
(zero_extract:SI (reg/v:SI 169 [ x ])
(const_int 1 [0x1])
(const_int 2 [0x2])))
(clobber (reg:SI 147 t))
]) sh_tmp.cpp:434 409 {any_treg_expr_to_reg}
(expr_list:REG_UNUSED (reg:SI 147 t)
(nil)))
...
(insn 16 15 17 2 (parallel [
(set (reg:SI 177 [ D.1733 ])
(zero_extract:SI (reg/v:SI 169 [ x ])
(const_int 1 [0x1])
(const_int 3 [0x3])))
(clobber (reg:SI 147 t))
]) sh_tmp.cpp:435 409 {any_treg_expr_to_reg}
(expr_list:REG_UNUSED (reg:SI 147 t)
(expr_list:REG_DEAD (reg/v:SI 169 [ x ])
(nil))))
Those pseudo-insns are then split into tst/bld/movt/movrt sequences in the
split1 pass. If a special shll/shlr pass is done right after combine and
before split1, it's possible to identify potential good shll/shlr sequences
rather easily and rewrite the code to use shll/shlr instead.