This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/63321] [SH] Unused T bit result of shll / shlr insns


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]