Hi, since recently, some of the PR 54089 tests started to fail. The attached patch fixes that.
Tested on rev 210305 with make -k check RUNTESTFLAGS="--target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" and no new failures. Committed as rev 210537. Cheers, Oleg gcc/ChangeLog: PR target/54089 * config/sh/predicates.md (negt_reg_shl31_operand): Match additional patterns. * config/sh/sh.md (*negt_msb): Merge SH2A and non-SH2A variants.
Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 210301) +++ gcc/config/sh/sh.md (working copy) @@ -11568,34 +11568,34 @@ ;; Store inverted T bit as MSB in a reg. ;; T = 0: 0x80000000 -> reg ;; T = 1: 0x00000000 -> reg -;; On SH2A we can get away without clobbering the T_REG. +;; On SH2A we can get away without clobbering the T_REG using the movrt insn. +;; On non SH2A we resort to the following sequence: +;; movt Rn +;; tst Rn,Rn +;; rotcr Rn +;; The T bit value will be modified during the sequence, but the rotcr insn +;; will restore its original value. (define_insn_and_split "*negt_msb" [(set (match_operand:SI 0 "arith_reg_dest") (match_operand:SI 1 "negt_reg_shl31_operand"))] - "TARGET_SH2A" + "TARGET_SH1" "#" "&& can_create_pseudo_p ()" [(const_int 0)] { rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_movrt (tmp, get_t_reg_rtx ())); - emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx)); - DONE; -}) -(define_insn_and_split "*negt_msb" - [(set (match_operand:SI 0 "arith_reg_dest") - (match_operand:SI 1 "negt_reg_shl31_operand")) - (clobber (reg:SI T_REG))] - "TARGET_SH1 && !TARGET_SH2A" - "#" - "&& can_create_pseudo_p ()" - [(const_int 0)] -{ - rtx tmp = gen_reg_rtx (SImode); - emit_move_insn (tmp, get_t_reg_rtx ()); - emit_insn (gen_cmpeqsi_t (tmp, const0_rtx)); - emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ())); + if (TARGET_SH2A) + { + emit_insn (gen_movrt (tmp, get_t_reg_rtx ())); + emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx)); + } + else + { + emit_move_insn (tmp, get_t_reg_rtx ()); + emit_insn (gen_cmpeqsi_t (tmp, const0_rtx)); + emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ())); + } DONE; }) Index: gcc/config/sh/predicates.md =================================================================== --- gcc/config/sh/predicates.md (revision 210301) +++ gcc/config/sh/predicates.md (working copy) @@ -1134,6 +1132,28 @@ (define_predicate "negt_reg_shl31_operand" (match_code "plus,minus,if_then_else") { + /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000 + (ashift:SI (match_operand:SI 1 "t_reg_operand") + (const_int 31))) + */ + if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0)) + && GET_CODE (XEXP (op, 1)) == ASHIFT + && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode) + && CONST_INT_P (XEXP (XEXP (op, 1), 1)) + && INTVAL (XEXP (XEXP (op, 1), 1)) == 31) + return true; + + /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand") + (const_int 31)) + (const_int -2147483648)) ;; 0xffffffff80000000 + */ + if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1)) + && GET_CODE (XEXP (op, 0)) == ASHIFT + && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode) + && CONST_INT_P (XEXP (XEXP (op, 0), 1)) + && INTVAL (XEXP (XEXP (op, 0), 1)) == 31) + return true; + /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand") (const_int -2147483648)) ;; 0xffffffff80000000 (const_int -2147483648))