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.