diff mbox

[PR,target/40977] Split ashldi_extsi

Message ID 52F55FD3.9000600@redhat.com
State New
Headers show

Commit Message

Jeff Law Feb. 7, 2014, 10:36 p.m. UTC
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 mbox

Patch

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")