This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/60071] [4.9 Regression] [SH] internal compiler error: in final_scan_insn, at final.c:2963


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60071

Oleg Endo <olegendo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-02-25
     Ever confirmed|0                           |1

--- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> ---
I've just tried this with -O2.  This is what happens...

After combine, there is the problematic insn:

(insn 41 40 34 3 (parallel [
            (set (reg:SI 161 [ <retval> ])
                (minus:SI (const_int -2147483648 [0xffffffff80000000])
                    (reg:SI 147 t)))
            (clobber (reg:SI 147 t))
        ]) sh_tmp.cpp:10 404 {*mov_t_msb_neg}
     (nil))


After split1 it is split correctly into constant load + negc and before the IRA
pass it looks like this:

(insn 45 40 46 4 (set (reg:SI 169)
        (const_int -2147483648 [0xffffffff80000000])) sh_tmp.cpp:10 257
{movsi_ie}
     (nil))
(insn 46 45 43 4 (parallel [
            (set (reg:SI 161 [ <retval> ])
                (minus:SI (neg:SI (reg:SI 169))
                    (reg:SI 147 t)))
            (clobber (reg:SI 147 t))
        ]) sh_tmp.cpp:10 205 {*negc}
     (nil))


However, the IRA pass moves the constant back and replaces the insn:

(insn 46 40 43 4 (parallel [
            (set (reg:SI 161 [ <retval> ])
                (minus:SI (const_int -2147483648 [0xffffffff80000000])
                    (reg:SI 147 t)))
            (clobber (reg:SI 147 t))
        ]) sh_tmp.cpp:10 404 {*mov_t_msb_neg}

which happens while can_create_pseudo_p () returns 'true', thus the insn
matches.  This is a bit counter productive.  The constant load was split out on
purpose so that it can be hoisted/combined easier (I was thinking of adding an
SH specific RTL pass to optimize constant loads and sharing.  On SH there are a
couple of cases where constants are emitted during combine and split1 which
won't be CSE'd).


The following seems to fix the problem (although not fully tested):

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md    (revision 208155)
+++ 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]