[Bug target/91635] wrong code at -O2 with __builtin_add_overflow() and shifts
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Sep 2 15:41:00 GMT 2019
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.
More information about the Gcc-bugs
mailing list