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

--- Comment #3 from Andreas Krebbel <krebbel at gcc dot gnu.org> ---
276.ira:

(insn 6 85 11 2 (set (reg:SI 100 [ f ])
        (mem/c:SI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) [2 f+0 S4 A32]))
"t.c":13:8 1372 {*movsi_zarch}
     (expr_list:REG_EQUIV (mem/c:SI (symbol_ref:DI ("*.LANCHOR0") [flags
0x182]) [2 f+0 S4 A32])
        (nil)))
...

(insn 87 75 207 2 (parallel [
            (set (mem/c:QI (plus:DI (reg/f:DI 165)
                        (const_int 16 [0x10])) [0 b+0 S1 A16])
                (and:QI (mem/c:QI (plus:DI (reg/f:DI 165)
                            (const_int 16 [0x10])) [0 b+0 S1 A16])
                    (subreg:QI (reg:SI 100 [ f ]) 3)))
            (clobber (reg:CC 33 %cc))
        ]) "t.c":13:8 1830 {*andqi3_zarch}
     (expr_list:REG_DEAD (reg/f:DI 165)
        (expr_list:REG_DEAD (reg:SI 100 [ f ])
            (expr_list:REG_UNUSED (reg:CC 33 %cc)
                (nil)))))

277.reload:

Reload at first generates two reloads for insn 87:

Changing pseudo 100 in operand 2 of insn 87 on equiv [`*.LANCHOR0']
      Creating newreg=202, assigning class ALL_REGS to slow/invalid mem r202
      Creating newreg=203, assigning class ALL_REGS to slow/invalid mem r203
   87: {[r165:DI+0x10]=[r165:DI+0x10]&r203:QI;clobber %cc:CC;}
      REG_DEAD r165:DI
      REG_DEAD r100:SI
      REG_UNUSED %cc:CC
    Inserting slow/invalid mem reload before:
  254: r202:SI=[`*.LANCHOR0']
  255: r203:QI=r202:SI#3

(insn 254 0 0 (set (reg:SI 202)
        (mem/c:SI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) [2 f+0 S4 A32]))
1372 {*movsi_zarch}
     (nil))
(insn 255 254 0 (set (reg:QI 203)
        (subreg:QI (reg:SI 202) 3)) -1
     (nil))


Both r202 as well as r203 get f0 assigned as hard register. In
lra_final_code_change-> alter_subregs-> alter_subreg -> simplify_subreg  this
gets simplified to:

(insn 255 254 256 2 (set (reg:QI 16 %f0 [203])
        (reg:QI 16 %f0 [orig:202+3 ] [202])) "t.c":13:8 1379 {*movqi}
     (expr_list:REG_DEAD (reg:SI 16 %f0 [202])
        (nil)))

Simplifying (subreg:QI (reg:SI 202) 3) to (reg:QI 16 %f0) is wrong on IBM Z
since floating point registers have a different endianess than general purpose
registers. Hence we forbid it via TARGET_CAN_CHANGE_MODE_CLASS. However, in
simplify_subreg_regno there is a check for lra_in_progress which leads to the
value of the target hook being ignored. Removing the lra_in_progress check
fixes the problem for. That change got in with the LRA patchset.

  /* Give the backend a chance to disallow the mode change.  */
  if (GET_MODE_CLASS (xmode) != MODE_COMPLEX_INT
      && GET_MODE_CLASS (xmode) != MODE_COMPLEX_FLOAT
      && !REG_CAN_CHANGE_MODE_P (xregno, xmode, ymode)
      /* We can use mode change in LRA for some transformations.  */
      && ! lra_in_progress)             <-----   ?
    return -1;

I'm currently checking whether removing it makes any difference in code
generation - apart from fixing the testcase.

Reply via email to