rtlanal: fix subreg handling in set_noop_p ()
authorIlya Leoshkevich <iii@linux.ibm.com>
Tue, 8 Sep 2020 23:23:51 +0000 (01:23 +0200)
committerIlya Leoshkevich <iii@linux.ibm.com>
Tue, 15 Sep 2020 17:30:37 +0000 (19:30 +0200)
The following s390 rtx is errneously considered a no-op:

(set (subreg:DF (reg:TF %f0) 8) (subreg:DF (reg:V1TF %f0) 8))

Here, SET_DEST is a second register in a floating-point register pair,
and SET_SRC is the second half of a vector register, so they refer to
different bits.

Fix by treating subregs of registers in different modes conservatively.

gcc/ChangeLog:

2020-09-11  Ilya Leoshkevich  <iii@linux.ibm.com>

* rtlanal.c (set_noop_p): Treat subregs of registers in
different modes conservatively.

gcc/rtlanal.c

index 5ae38b7966d9ed47f0e6bfb41853ebf81453b0de..01130a10783d63d7dc541eaf70743241fa15394f 100644 (file)
@@ -1619,6 +1619,10 @@ set_noop_p (const_rtx set)
        return 0;
       src = SUBREG_REG (src);
       dst = SUBREG_REG (dst);
+      if (GET_MODE (src) != GET_MODE (dst))
+       /* It is hard to tell whether subregs refer to the same bits, so act
+          conservatively and return 0.  */
+       return 0;
     }
 
   /* It is a NOOP if destination overlaps with selected src vector