diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 316ca15473eeaf2c176bbb057edc6c14bf87705a..54fe27c5da37008c02df6b294f02ea85bd848257 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-11-25  Andrew Pinski <pinskia@physics.uc.edu>
+
+	parts of PR rtl-opt/18463, rtl-opt/17647
+	* cse.c (canon_for_address): New function.
+	(find_best_addr): Call canon_for_address before getting the
+	address's cost when checking if we should take that address.
+
 2004-11-25  Kazu Hirata  <kazu@cs.umass.edu>
 
 	* tree-phinodes.c (add_phi_arg): Take "tree" instead of
diff --git a/gcc/cse.c b/gcc/cse.c
index 0858b0252b8fa0bf5ea2fd944d979a7a9427c1c0..9ea5297caaff86697a5941d3830f64576e3949a6 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -761,6 +761,57 @@ approx_reg_cost (rtx x)
   return cost;
 }
 
+/* Returns a canonical version of X for the address, from the point of view,
+   that all multiplications are repesented as MULT instead of the multiply
+   by a power of 2 being repesented as ASHIFT.  */
+
+static rtx
+canon_for_address (rtx x)
+{
+  enum rtx_code code;
+  enum machine_mode mode;
+  rtx new = 0;
+  int i;
+  const char *fmt;
+  
+  if (!x)
+    return x;
+  
+  code = GET_CODE (x);
+  mode = GET_MODE (x);
+  
+  switch (code)
+    {
+    case ASHIFT:
+      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+	  && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)
+	  && INTVAL (XEXP (x, 1)) >= 0)
+        {
+	  new = canon_for_address (XEXP (x, 0));
+	  new = gen_rtx_MULT (mode, new,
+			      gen_int_mode ((HOST_WIDE_INT) 1
+				            << INTVAL (XEXP (x, 1)),
+					    mode));
+	}
+      break;
+    default:
+      break;
+      
+    }
+  if (new)
+    return new;
+  
+  /* Now recursively process each operand of this operation.  */
+  fmt = GET_RTX_FORMAT (code);
+  for (i = 0; i < GET_RTX_LENGTH (code); i++)
+    if (fmt[i] == 'e')
+      {
+	new = canon_for_address (XEXP (x, i));
+	XEXP (x, i) = new;
+      }
+  return x;
+}
+
 /* Return a negative value if an rtx A, whose costs are given by COST_A
    and REGCOST_A, is more desirable than an rtx B.
    Return a positive value if A is less desirable, or 0 if the two are
@@ -2933,6 +2984,11 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
 		rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
 					       p->exp, op1);
 		int new_cost;
+		
+		/* Get the canonical version of the address so we can accept
+		   more. */
+		new = canon_for_address (new);
+		
 		new_cost = address_cost (new, mode);
 
 		if (new_cost < best_addr_cost