https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115576

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Testcase in C:
struct S
{
  unsigned long long a;
  signed char b, c;
  unsigned short d;
};

struct T
{
  unsigned int a;
  signed char b, c;
  unsigned short d;
};

struct S
foo (const struct T *x)
{
  return (struct S) { x->a, x->b, x->c, x->d };
}

I'm afraid combine can't do much, as it generally tries to combine a pseudo
setter with its single user, that isn't something that is done here, most of
the TImode setters have 2+ users.
E.g. that
(insn 23 22 8 2 (set (reg:TI 101 [ D.2787 ])
        (const_int 0 [0])) "pr115576.c":18:10 -1
     (nil))
(insn 8 23 9 2 (set (reg:TI 101 [ D.2787 ])
        (ior:TI (and:TI (reg:TI 101 [ D.2787 ])
                (const_wide_int 0xffffffffffffffff0000000000000000))
            (zero_extend:TI (reg:DI 104 [ _2 ])))) "pr115576.c":18:10 140
{*insvti_lowpart_1}
     (expr_list:REG_DEAD (reg:DI 104 [ _2 ])
        (nil)))
is used in both
(insn 10 9 11 2 (set (reg:DI 106)
        (subreg:DI (reg:TI 101 [ D.2787 ]) 8)) "pr115576.c":18:10 88
{*movdi_internal}
     (nil))
and
(insn 14 13 19 2 (set (reg:TI 101 [ D.2787 ])
        (ior:TI (and:TI (reg:TI 101 [ D.2787 ])
                (const_wide_int 0x0ffffffffffffffff))
            (ashift:TI (zero_extend:TI (reg:DI 109))
                (const_int 64 [0x40])))) "pr115576.c":18:10 137
{*insvti_highpart_1}
     (expr_list:REG_DEAD (reg:DI 109)
        (nil)))

What would generally help is if nonzero_bits was able to deal with this and say
that all bits in (subreg:DI (reg:TI 101 [ D.2787 ]) 8) are zero.
But, nonzero_bits etc. uses unfortunately unsigned HOST_WIDE_INT rather than
say wide_int or offset_int or FIXED_WIDE_INT (128) or some other type that can
store more than 64 bits.
Though, say on 32-bit targets unsigned HOST_WIDE_INT is probably good enough.

Reply via email to