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

            Bug ID: 79121
           Summary: [6, 7 regression] invalid expansion of sign-extend
                    unsigned plus left shift
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rearnsha at gcc dot gnu.org
                CC: jiwang at gcc dot gnu.org
  Target Milestone: ---
            Target: arm-* mips-*

In the following, the conversion to long long requires a zero extend, however
the expanders use an arithmetic right shift to generate the high-part word.

long long dohash(unsigned x) {
        return ((long long)x) << 4;
}

On ARM this generates 

        mov     r1, r0
        lsl     r0, r0, #4
        asr     r1, r1, #28   // Should be lsr
        bx      lr

Similarly on MIPS:

        sll     $3,$4,4
        .set    noreorder
        .set    nomacro
        jr      $31
        sra     $2,$4,28    // should be srl


Possibly introduced by this patch:
r227018 
Author: jiwang <jiwang@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Aug 19 22:55:28 2015 +0000

    [Patch][expand] Check gimple statement to improve LSHIFT_EXP expand

    This patch improves LSHIFT_EXP expand if the shift operand comes from sign
    extension and the shift result across word_mode_size boundary. See code
    comments for details.

    2015-08-19  Jiong.Wang  <jiong.w...@arm.com>

    gcc/
      * expr.c (expand_expr_real_2): Check gimple statement during
      LSHIFT_EXPR expand.

Reply via email to