This is the mail archive of the gcc-patches@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]

[PR target/40977] Split ashldi_extsi


As outlined in the PR, we end up generating poor code because of the existence of the ashldi_extsi insn in the m68k backend.

The pattern recognizes that left shifting a DImode value by 32 deposits the low part of the input into the high part of the output and clears the low part of the output.

That's a fine thing to recognize, except that it's a two instruction insn. If (for example) the next insn happens to overwrite those low bits then the clearing done by the 2nd instruction generated by ashldi_extsi is dead.

The obvious way to fix this is to turn the pattern into a define_insn_and_split. One could certainly make an argument that to the extent possible every insn that generates multiple instructions like this ought to turn into a define_insn_and_split. However, I don't think there's enough interest in the m68k port to warrant the time spent.

Tested by building m68k cross and verifying correct output for the testcase. Installed on the trunk.


diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce9c066..1237904 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
 2014-02-07  Jeff Law  <law@redhat.com>
 
+	PR target/40977
+	* config/m68k/m68k.md (ashldi_extsi): Turn into a
+	define_insn_and_split.
+
 	* ipa-inline.c (inline_small_functions): Fix typos.
 
 2014-02-07  Richard Sandiford  <rsandifo@linux.vnet.ibm.com>
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 7bf9abd..e61048b 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -4338,25 +4338,18 @@
 
 ;; arithmetic shift instructions
 ;; We don't need the shift memory by 1 bit instruction
-
-(define_insn "ashldi_extsi"
+(define_insn_and_split "ashldi_extsi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
     (ashift:DI
       (match_operator:DI 2 "extend_operator"
         [(match_operand:SI 1 "general_operand" "rm")])
       (const_int 32)))]
   ""
-{
-  CC_STATUS_INIT;
-  if (GET_CODE (operands[0]) == REG)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  else
-    operands[2] = adjust_address (operands[0], SImode, 4);
-  if (ADDRESS_REG_P (operands[0]))
-    return "move%.l %1,%0\;sub%.l %2,%2";
-  else
-    return "move%.l %1,%0\;clr%.l %2";
-})
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (const_int 0))]
+  "split_di(operands, 1, operands + 2, operands + 3);")
 
 (define_insn "ashldi_sexthi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]