From: Oleg Endo Date: Sat, 1 Mar 2014 13:16:37 +0000 (+0000) Subject: re PR target/60071 ([SH] internal compiler error: in final_scan_insn, at final.c... X-Git-Tag: releases/gcc-4.9.0~621 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19305875c254f3eb3089f2f49737a0138ca7f1a5;p=thirdparty%2Fgcc.git re PR target/60071 ([SH] internal compiler error: in final_scan_insn, at final.c:2963) PR target/60071 * config/sh/sh.md (*mov_t_msb_neg): Split into ... (*mov_t_msb_neg_negc): ... this new insn. PR target/60071 * gcc.c-torture/compile/pr60071.c: New. From-SVN: r208242 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56da66051d2d..c7936eafaed7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-03-01 Oleg Endo + + PR target/60071 + * config/sh/sh.md (*mov_t_msb_neg): Split into ... + (*mov_t_msb_neg_negc): ... this new insn. + 2014-02-28 Jason Merrill PR c++/58678 diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 410e9689db4e..76af3a2e18b7 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -11434,6 +11434,10 @@ label: ;; T = 1: 0x80000000 -> reg ;; T = 0: 0x7FFFFFFF -> reg ;; This works because 0 - 0x80000000 = 0x80000000. +;; +;; This insn must not match again after it has been split into the constant +;; load and negc. This is accomplished by the special negc insn that +;; has a use on the operand. (define_insn_and_split "*mov_t_msb_neg" [(set (match_operand:SI 0 "arith_reg_dest") (minus:SI (const_int -2147483648) ;; 0x80000000 @@ -11444,12 +11448,23 @@ label: "&& can_create_pseudo_p ()" [(set (match_dup 2) (const_int -2147483648)) (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2)) - (reg:SI T_REG))) - (clobber (reg:SI T_REG))])] + (reg:SI T_REG))) + (clobber (reg:SI T_REG)) + (use (match_dup 2))])] { operands[2] = gen_reg_rtx (SImode); }) +(define_insn "*mov_t_msb_neg_negc" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")) + (match_operand:SI 2 "t_reg_operand"))) + (clobber (reg:SI T_REG)) + (use (match_dup 1))] + "TARGET_SH1" + "negc %1,%0" + [(set_attr "type" "arith")]) + ;; These are essentially the same as above, but with the inverted T bit. ;; Combine recognizes the split patterns, but does not take them sometimes ;; if the T_REG clobber is specified. Instead it tries to split out the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a831bfdd5cc..d7ef999776da 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-03-01 Oleg Endo + + PR target/60071 + * gcc.c-torture/compile/pr60071.c: New. + 2014-02-28 Janus Weil PR fortran/60359 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr60071.c b/gcc/testsuite/gcc.c-torture/compile/pr60071.c new file mode 100644 index 000000000000..8bc2c1f4f58d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr60071.c @@ -0,0 +1,8 @@ +int +foo (int cls, int sign) +{ + if (__builtin_expect (cls == 4, 0)) + return (sign + ? (-((int) ((~(unsigned)0) >> 1)))-1 + : ((int) ((~(unsigned)0) >> 1))); +}