diff mbox

[SH,committed] Fix PR 60071

Message ID 1393680069.7310.70.camel@yam-132-YW-E178-FTW
State New
Headers show

Commit Message

Oleg Endo March 1, 2014, 1:21 p.m. UTC
Hi,

I've just committed the attached patch that fixes PR 60071 as rev
208242.  Originally tested by Kaz:
http://gcc.gnu.org/ml/gcc-testresults/2014-02/msg01866.html
Tested the new test case with:
make check-gcc RUNTESTFLAGS="compile.exp=pr60071.c --target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

Cheers,
Oleg

gcc/ChangeLog:
	PR target/60071
	* config/sh/sh.md (*mov_t_msb_neg): Split into ...
	(*mov_t_msb_neg_negc): ... this new insn.

testsuite/ChangeLog:
	PR target/60071
	* gcc.c-torture/compile/pr60071.c: New.
diff mbox

Patch

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 208241)
+++ gcc/config/sh/sh.md	(working copy)
@@ -11434,6 +11434,10 @@ 
 ;;	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 @@ 
   "&& 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
Index: gcc/testsuite/gcc.c-torture/compile/pr60071.c
===================================================================
--- gcc/testsuite/gcc.c-torture/compile/pr60071.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr60071.c	(revision 0)
@@ -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)));
+}