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

            Bug ID: 78904
           Summary: zero-extracts are not effective
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

Following testcase:

--cut here--
struct S1
{
  char pad1;
  unsigned char val;
  short pad2;
};

struct S1 test (struct S1 a, struct S1 b)
{
  struct S1 r = a;

  r.val = a.val + b.val;

  return r;
}
--cut here--

should be compiled to something involving:

addb %dh, %ah

but is compiled to a whole sequence of:

        movl    %edi, %ecx
        movl    %esi, %eax
        xorl    %edx, %edx
        movzbl  %ch, %esi
        movzbl  %ah, %eax
        movb    %dil, %dl
        addl    %esi, %eax
        xorw    %di, %di
        movb    %al, %dh
        movzwl  %dx, %eax
        orl     %edi, %eax

The relevant patterns from i386.md are:

(define_insn "addqi_ext_1"
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
                         (const_int 8)
                         (const_int 8))
        (plus:SI
          (zero_extract:SI
            (match_operand 1 "ext_register_operand" "0,0")
            (const_int 8)
            (const_int 8))
          (match_operand:QI 2 "general_operand" "Qn,Bn")))
   (clobber (reg:CC FLAGS_REG))]

and

(define_insn "*addqi_ext_2"
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
                         (const_int 8)
                         (const_int 8))
        (plus:SI
          (zero_extract:SI
            (match_operand 1 "ext_register_operand" "%0")
            (const_int 8)
            (const_int 8))
          (zero_extract:SI
            (match_operand 2 "ext_register_operand" "Q")
            (const_int 8)
            (const_int 8))))
   (clobber (reg:CC FLAGS_REG))]

Combine pass tries to generate something resembling the above patterns:

(set (zero_extract:SI (reg:SI 92 [ D.1804 ])
        (const_int 8 [0x8])
        (const_int 8 [0x8]))
    (subreg:SI (plus:QI (subreg:QI (zero_extract:SI (reg/v:SI 95 [ b ])
                    (const_int 8 [0x8])
                    (const_int 8 [0x8])) 0)
            (reg:QI 98 [ a$val ])) 0))

but it looks that the pattern is not fully canonicalized and thus not
recognized.

Reply via email to