diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 9a726f1..011f294 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -1169,6 +1169,37 @@ normalize_cond_1 (gimple cond,
                         norm_cond, cur_cond_code);
       norm_cond->cond_code = cur_cond_code;
     }
+  else if (TREE_CODE_CLASS (cur_cond_code) == tcc_ccomparison
+	   && (cond_code == cur_cond_code || cond_code == ERROR_MARK))
+    {
+      tree rhs3 = gimple_assign_rhs3 (cond);
+      enum tree_code ncode, icode;
+
+      ncode = get_code_from_ccompare_expr (&icode, cur_cond_code);
+
+      if (TREE_CODE (rhs3) == SSA_NAME)
+	{
+	  normalize_cond_1 (SSA_NAME_DEF_STMT (rhs3),
+			    norm_cond, cur_cond_code);
+	}
+      if (ncode == NE_EXPR)
+	{
+	  if (integer_zerop (rhs2)
+	      && (TREE_CODE (rhs1) == SSA_NAME))
+	     normalize_cond_1 (SSA_NAME_DEF_STMT (rhs1),
+			       norm_cond, cur_cond_code);
+	  else if (integer_zerop (rhs1)
+		   && (TREE_CODE (rhs2) == SSA_NAME))
+	     normalize_cond_1 (SSA_NAME_DEF_STMT (rhs2),
+			       norm_cond, cur_cond_code);
+	  else
+	     norm_cond->conds.safe_push (cond);
+	}
+	else
+	  norm_cond->conds.safe_push (cond);
+
+       norm_cond->cond_code = cur_cond_code;
+    }
   else
     norm_cond->conds.safe_push (cond);
 }
@@ -1214,7 +1245,8 @@ normalize_cond (gimple cond, norm_cond_t norm_cond, bool invert)
     }
 
   gcc_assert (norm_cond->conds.length () == 1
-              || is_and_or_or (norm_cond->cond_code, NULL));
+	      || is_and_or_or (norm_cond->cond_code, NULL)
+	      || TREE_CODE_CLASS (norm_cond->cond_code) == tcc_ccomparison);
 }
 
 /* Returns true if the domain for condition COND1 is a subset of
@@ -1228,7 +1260,7 @@ is_gcond_subset_of (gimple cond1, bool invert1,
                     bool reverse)
 {
   enum gimple_code gc1, gc2;
-  enum tree_code cond1_code, cond2_code;
+  enum tree_code cond1_code, cond2_code, tmp_code;
   gimple tmp;
   tree cond1_lhs, cond1_rhs, cond2_lhs, cond2_rhs;
 
@@ -1258,6 +1290,11 @@ is_gcond_subset_of (gimple cond1, bool invert1,
                 ? gimple_assign_rhs_code (cond2)
                 : gimple_cond_code (cond2));
 
+  if (TREE_CODE_CLASS (cond1_code) == tcc_ccomparison)
+    cond1_code = get_code_from_ccompare_expr (&tmp_code, cond1_code);
+  if (TREE_CODE_CLASS (cond2_code) == tcc_ccomparison)
+    cond2_code = get_code_from_ccompare_expr (&tmp_code, cond2_code);
+
   if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
       || TREE_CODE_CLASS (cond2_code) != tcc_comparison)
     return false;
@@ -1428,8 +1465,53 @@ is_norm_cond_subset_of (norm_cond_t norm_cond1,
 
   code1 = norm_cond1->cond_code;
   code2 = norm_cond2->cond_code;
+  if (TREE_CODE_CLASS (code1) == tcc_ccomparison)
+    {
+      enum tree_code icode1, icode2 = code2;
+      get_code_from_ccompare_expr (&icode1, code1);
+      if (TREE_CODE_CLASS (code2) == tcc_ccomparison)
+	{
+	  get_code_from_ccompare_expr (&icode2, code2);
+	}
+      if (icode1 == BIT_AND_EXPR)
+	{
+	  /* Both conditions are AND expressions.  */
+	  if (icode2 == BIT_AND_EXPR)
+	    return is_and_set_subset_of (norm_cond1, norm_cond2);
+
+	  /* NORM_COND1 is an AND expression, and NORM_COND2 is an OR
+	     expression.  In this case, returns true if any subexpression
+	     of NORM_COND1 is a subset of any subexpression of NORM_COND2.  */
+	  else if (icode2 == BIT_IOR_EXPR)
+	    {
+	      size_t len1;
+	      len1 = norm_cond1->conds.length ();
+	      for (i = 0; i < len1; i++)
+		{
+		  gimple cond1 = norm_cond1->conds[i];
+		  if (is_subset_of_any (cond1, false, norm_cond2, false))
+		    return true;
+		}
+	      return false;
+	    }
+	  else
+	    {
+	      gcc_assert (code2 == ERROR_MARK);
+	      gcc_assert (norm_cond2->conds.length () == 1);
+	      return is_subset_of_any (norm_cond2->conds[0],
+				       norm_cond2->invert, norm_cond1, true);
+	    }
+	}
+      else
+	{
+	  gcc_assert (icode1 == BIT_IOR_EXPR);
+	  if (icode2 != icode1)
+	    return false;
 
-  if (code1 == BIT_AND_EXPR)
+	  return is_or_set_subset_of (norm_cond1, norm_cond2);
+	}
+    }
+  else if (code1 == BIT_AND_EXPR)
     {
       /* Both conditions are AND expressions.  */
       if (code2 == BIT_AND_EXPR)
@@ -1469,6 +1551,9 @@ is_norm_cond_subset_of (norm_cond_t norm_cond1,
     {
       gcc_assert (code1 == ERROR_MARK);
       gcc_assert (norm_cond1->conds.length () == 1);
+
+      if (TREE_CODE_CLASS (code2) == tcc_ccomparison)
+	get_code_from_ccompare_expr (&code2, code2);
       /* Conservatively returns false if NORM_COND1 is non-decomposible
          and NORM_COND2 is an AND expression.  */
       if (code2 == BIT_AND_EXPR)
