diff --git a/gcc/combine.c b/gcc/combine.c
index d3305cb..0f1d315 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -423,6 +423,9 @@ static rtx simplify_shift_const_1 (enum rtx_code, enum machine_mode, rtx, int);
 static rtx simplify_shift_const (rtx, enum rtx_code, enum machine_mode, rtx,
 				 int);
 static int recog_for_combine (rtx *, rtx, rtx *);
+static rtx simplify_gen_subreg_for_combine (enum machine_mode, rtx,
+					    enum machine_mode,
+					    unsigned int);
 static rtx gen_lowpart_for_combine (enum machine_mode, rtx);
 static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
 static void update_table_tick (rtx);
@@ -7482,6 +7485,20 @@ canon_reg_for_combine (rtx x, rtx reg)
   return x;
 }
 
+/* Like simplify_gen_subreg but for use by combine.  Return NULL_RTX
+   if it is called with invalid combination of OUTERMODE, OP and
+   INNERMODE.  */
+
+static rtx
+simplify_gen_subreg_for_combine (enum machine_mode outermode, rtx op,
+				 enum machine_mode innermode,
+				 unsigned int byte)
+{
+  if (GET_MODE (op) != innermode && GET_MODE (op) != VOIDmode)
+    return NULL_RTX;
+  return simplify_gen_subreg (outermode, op, innermode, byte);
+}
+
 /* Return X converted to MODE.  If the value is already truncated to
    MODE we can just return a subreg even though in the general case we
    would need an explicit truncation.  */
@@ -8222,10 +8239,12 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
 	   && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
 					       &true0, &false0)))
     {
-      true0 = simplify_gen_subreg (mode, true0,
-				   GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
-      false0 = simplify_gen_subreg (mode, false0,
-				    GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
+      true0 = simplify_gen_subreg_for_combine (mode, true0,
+					       GET_MODE (SUBREG_REG (x)),
+					       SUBREG_BYTE (x));
+      false0 = simplify_gen_subreg_for_combine (mode, false0,
+						GET_MODE (SUBREG_REG (x)),
+						SUBREG_BYTE (x));
       if (true0 && false0)
 	{
 	  *ptrue = true0;
--- /dev/null	2010-06-16 10:11:06.602750711 -0700
+++ gcc/gcc/testsuite/gcc.dg/torture/pr44695.c	2010-06-29 11:49:12.186942482 -0700
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+typedef unsigned char uint8_t;
+
+static uint8_t
+safe_div_func_uint8_t_u_u (uint8_t ui1, uint8_t ui2)
+{
+  return ui2 ? ui2 : (ui1 / ui2);
+}
+
+int
+int81 (int x)
+{
+  return safe_div_func_uint8_t_u_u (1, 8 & x);
+}
