A few define_split's in the i386 backend modify RTL in place.  This does
not work.  This patch fixes all cases that do PUT_MODE on existing RTL.

Bootstrapped and tested; no regressions.  Is this okay for trunk?

Hrm, this wants the testcase in that PR added I suppose.  Will send
it separately.


Segher


2015-06-24  Segher Boessenkool  <seg...@kernel.crashing.org>

        * config/i386/i386.md (various splitters): Use copy_rtx before
        doing PUT_MODE on operands.

---
 gcc/config/i386/i386.md |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d75b2e1..5425cec 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10865,7 +10865,10 @@
            (const_int 0)))]
   ""
   [(set (match_dup 0) (match_dup 1))]
-  "PUT_MODE (operands[1], QImode);")
+{
+  operands[1] = copy_rtx (operands[1]);
+  PUT_MODE (operands[1], QImode);
+})
 
 (define_split
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
@@ -10874,7 +10877,10 @@
            (const_int 0)))]
   ""
   [(set (match_dup 0) (match_dup 1))]
-  "PUT_MODE (operands[1], QImode);")
+{
+  operands[1] = copy_rtx (operands[1]);
+  PUT_MODE (operands[1], QImode);
+})
 
 (define_split
   [(set (match_operand:QI 0 "nonimmediate_operand")
@@ -11031,7 +11037,10 @@
        (if_then_else (match_dup 0)
                      (label_ref (match_dup 1))
                      (pc)))]
-  "PUT_MODE (operands[0], VOIDmode);")
+{
+  operands[0] = copy_rtx (operands[0]);
+  PUT_MODE (operands[0], VOIDmode);
+})
 
 (define_split
   [(set (pc)
@@ -17298,6 +17307,7 @@
   operands[1] = gen_lowpart (SImode, operands[1]);
   if (GET_CODE (operands[3]) != ASHIFT)
     operands[2] = gen_lowpart (SImode, operands[2]);
+  operands[3] = copy_rtx (operands[3]);
   PUT_MODE (operands[3], SImode);
 })
 
-- 
1.7.10.4

Reply via email to