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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrew at sifive dot com,
                   |                            |kito at gcc dot gnu.org,
                   |                            |palmer at gcc dot gnu.org,
                   |                            |wilson at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Looks like a backend bug to me.

Trying 12, 13 -> 14:
   12: r85:SI=r72:DI#0<<0x1
      REG_DEAD r72:DI
   13: r76:DI=zero_extend(r85:SI#0)
      REG_DEAD r85:SI
   14: r87:SI=r76:DI#0 0>>0x1
      REG_DEAD r76:DI
Failed to match this instruction:
(set (subreg:DI (reg:SI 87) 0)
    (and:DI (reg:DI 72 [ _1 ])
        (const_int 32767 [0x7fff])))
Splitting with gen_split_35
Successfully matched this instruction:
(set (subreg:DI (reg:SI 87) 0)
    (ashift:DI (reg:DI 72 [ _1 ])
        (const_int 49 [0x31])))
Successfully matched this instruction:
(set (subreg:DI (reg:SI 87) 0)
    (lshiftrt:DI (subreg:DI (reg:SI 87) 0)
        (const_int 49 [0x31])))

That splitting through gen_split_35 is incorrect in reusing the paradoxical
subreg destination for the intermediate result, because in a paradoxical subreg
the high bits are undefined, while the splitter relies on them being defined.

--- gcc/config/riscv/riscv.md.jj        2019-07-08 23:52:53.000000000 +0200
+++ gcc/config/riscv/riscv.md   2019-09-02 17:18:26.909424288 +0200
@@ -1770,15 +1770,17 @@
   [(set (match_operand:GPR 0 "register_operand")
        (and:GPR (match_operand:GPR 1 "register_operand")
                 (match_operand:GPR 2 "p2m1_shift_operand")))]
-  ""
- [(set (match_dup 0)
+  "can_create_pseudo_p () || !paradoxical_subreg_p (operands[0])"
+ [(set (match_dup 3)
        (ashift:GPR (match_dup 1) (match_dup 2)))
   (set (match_dup 0)
-       (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
+       (lshiftrt:GPR (match_dup 3) (match_dup 2)))]
 {
   /* Op2 is a VOIDmode constant, so get the mode size from op1.  */
   operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
                         - exact_log2 (INTVAL (operands[2]) + 1));
+  operands[3]
+    = can_create_pseudo_p () ? gen_reg_rtx (<MODE>mode) : operands[0];
 })

 ;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros.  This can be
@@ -1787,13 +1789,15 @@
   [(set (match_operand:DI 0 "register_operand")
        (and:DI (match_operand:DI 1 "register_operand")
                (match_operand:DI 2 "high_mask_shift_operand")))]
-  "TARGET_64BIT"
-  [(set (match_dup 0)
+  "TARGET_64BIT
+   && (can_create_pseudo_p () || !paradoxical_subreg_p (operands[0]))"
+  [(set (match_dup 3)
        (lshiftrt:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
-       (ashift:DI (match_dup 0) (match_dup 2)))]
+       (ashift:DI (match_dup 3) (match_dup 2)))]
 {
   operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
+  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[0];
 })

 ;;

fixes this, but I don't have a way to test riscv, plus the backend has several
similar problems elsewhere.

Reply via email to