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

            Bug ID: 84071
           Summary: [7/8 regression] nonzero_bits1 of subreg incorrect
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wilco at gcc dot gnu.org
  Target Milestone: ---

PR59461 changed nonzero_bits1 incorrectly for subregs:

          /* On many CISC machines, accessing an object in a wider mode
             causes the high-order bits to become undefined.  So they are
             not known to be zero.  */
          rtx_code extend_op;
          if ((!WORD_REGISTER_OPERATIONS
               /* If this is a typical RISC machine, we only have to worry
                  about the way loads are extended.  */
               || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND
                   ? val_signbit_known_set_p (inner_mode, nonzero)
                   : extend_op != ZERO_EXTEND)
               || (!MEM_P (SUBREG_REG (x)) && !REG_P (SUBREG_REG (x))))
              && xmode_width > inner_width)
            nonzero
              |= (GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK (inner_mode));

If WORD_REGISTER_OPERATIONS is set and load_extend_op is ZERO_EXTEND, rtl like

(subreg:SI (reg:HI 125) 0)

is assumed to be always zero-extended. This is incorrect since modes that are
smaller than WORD_MODE may contain random top bits. This is equally true for
RISC and CISC ISAs and independent of WORD_REGISTER_OPERATIONS, so it's unclear
why the !REG_P check was added.

On ARM this causes the following bug:

arm-none-eabi-gcc -march=armv7-a -marm -O2 -S -o- -mbig-endian

typedef union 
{
  signed short ss;
  unsigned short us;
  int x;
} U;

int f(int x, int y, int z, int a, U u)
{
  return (u.ss <= 0) + u.us;
}

        ldrsh   r3, [sp]
        sxth    r0, r3
        cmp     r0, #0  // correctly uses sign-extended value
        movgt   r0, r3  // wrong - must be zero-extended!!!
        addle   r0, r3, #1
        bx      lr

Reply via email to