diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bc9fb613629c5f9be24ce666d6832de478ea3e6f..9b79868280a7365f6c910b808a9a435363b538c9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-17  Uros Bizjak  <uros@kss-loka.si>
+
+	PR rtl-optimization/15187
+	* ifcvt.c (noce_try_cmove_arith): Exit early if total
+	insn_rtx_cost of both branches > BRANCH_COST
+
 2004-09-16  Diego Novillo  <dnovillo@redhat.com>
 
 	PR tree-optimization/17528
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 0767eb25008a537fa46c2309f3aacef0a0abfcd3..5963158db42f988436757ced24131866fbd46ba9 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1214,6 +1214,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   rtx insn_a, insn_b;
   rtx tmp, target;
   int is_mem = 0;
+  int insn_cost;
   enum rtx_code code;
 
   /* A conditional move from two memory sources is equivalent to a
@@ -1247,6 +1248,25 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   insn_a = if_info->insn_a;
   insn_b = if_info->insn_b;
 
+  /* Total insn_rtx_cost should be smaller than branch cost.  Exit
+     if insn_rtx_cost can't be estimated.  */
+  if (insn_a)
+    {
+      insn_cost = insn_rtx_cost (PATTERN (insn_a));
+      if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
+	return FALSE;
+    }
+  else
+    {
+      insn_cost = 0;
+    }
+
+  if (insn_b) {
+    insn_cost += insn_rtx_cost (PATTERN (insn_b));
+    if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
+      return FALSE;
+  }
+
   /* Possibly rearrange operands to make things come out more natural.  */
   if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
     {