diff --git a/gcc/testsuite/gcc.dg/tree-ssa/abs-2.c b/gcc/testsuite/gcc.dg/tree-ssa/abs-2.c
index 328b180254124afd645f63902ddf2b844e63eff4..f8bbeb43237320c35533fab2904d0705e93e2b63 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/abs-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/abs-2.c
@@ -16,5 +16,5 @@ test_abs(int *cur)
 
 /* We should figure out that test_abs has an ABS_EXPR in it. */
 /* { dg-final { scan-tree-dump " = ABS_EXPR" "phiopt1"} } */
-/* { dg-final { scan-tree-dump-times "changed to factor conversion out from" 1 "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from" 1 "phiopt1"} } */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c
index bd737e6b4cb2e5cb9a03ed72affb277c6d79fe5b..7c76cfc62a906a42850a2e3dabf09fe7db8f74af 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c
@@ -18,4 +18,4 @@ unsigned long long test_max(int c, int d, int e)
 
 /* We should figure out that test_max has an MAX_EXPR in it. */
 /* { dg-final { scan-tree-dump " = MAX_EXPR" "phiopt1"} } */
-/* { dg-final { scan-tree-dump-times "changed to factor conversion out from" 2 "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from" 2 "phiopt1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-18.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-18.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8e1670f64a72a07d871d7680bb4eb178169e737
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-18.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-phiopt1-details" } */
+
+static inline unsigned long long g(int t)
+{
+  unsigned t1 = t;
+  return t1;
+}
+static inline int abs1(int a)
+{
+  if (a < 0)
+    a = -a;
+  return a;
+}
+unsigned long long f(int c, int d, int e)
+{
+  unsigned long long t;
+  if (d > e)
+    t = g(abs1(d));
+  else
+    t = g(abs1(e));
+  return t;
+}
+
+/* { dg-final { scan-tree-dump " = MAX_EXPR" "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times " = ABS_EXPR" 2 "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from" 3 "phiopt1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-19.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-19.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ed55fe2e232c7dcf9b9310e6bfd32a4914a99eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-19.c
@@ -0,0 +1,10 @@
+/* PR tree-optimization/109424 */
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-phiopt1-details" } */
+
+int f2(int x, int y)
+{
+    return (x > y) ? ~x : ~y;
+}
+/* { dg-final { scan-tree-dump " = MAX_EXPR" "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from" 1 "phiopt1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr103771.c b/gcc/testsuite/gcc.dg/tree-ssa/pr103771.c
index 97c9db846cb7ff368fe009a8569cd51ec0f37c64..8faa45a8222e34405507e5fd288b1311a822c0bc 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr103771.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr103771.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O3 -fdump-tree-phiopt1-details" } */
-/* { dg-final { scan-tree-dump-times "changed to factor conversion out from COND_EXPR." 1 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "changed to factor operation out from COND_EXPR." 1 "phiopt1" } } */
 
 typedef unsigned char uint8_t;
 
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 7fe088b13ff25fbb41bc6e22eb7c3fc45f8f6c98..2fb28b4e60ed53c77cececa7ee619d93b0083b91 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -209,13 +209,13 @@ replace_phi_edge_with_variable (basic_block cond_block,
 	      bb->index);
 }
 
-/* PR66726: Factor conversion out of COND_EXPR.  If the arguments of the PHI
+/* PR66726: Factor operations out of COND_EXPR.  If the arguments of the PHI
    stmt are CONVERT_STMT, factor out the conversion and perform the conversion
    to the result of PHI stmt.  COND_STMT is the controlling predicate.
    Return the newly-created PHI, if any.  */
 
 static gphi *
-factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
+factor_out_conditional_operation (edge e0, edge e1, gphi *phi,
 				   tree arg0, tree arg1, gimple *cond_stmt)
 {
   gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL, *new_stmt;
@@ -224,7 +224,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
   gphi *newphi;
   gimple_stmt_iterator gsi, gsi_for_def;
   location_t locus = gimple_location (phi);
-  enum tree_code convert_code;
+  enum tree_code op_code;
 
   /* Handle only PHI statements with two arguments.  TODO: If all
      other arguments to PHI are INTEGER_CST or if their defining
@@ -246,15 +246,17 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
     return NULL;
 
   /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is
-     a conversion.  */
+     an unary operation.  */
   arg0_def_stmt = SSA_NAME_DEF_STMT (arg0);
-  if (!gimple_assign_cast_p (arg0_def_stmt))
+  if (!is_gimple_assign (arg0_def_stmt)
+      || (gimple_assign_rhs_class (arg0_def_stmt) != GIMPLE_UNARY_RHS
+	  && gimple_assign_rhs_code (arg0_def_stmt) != VIEW_CONVERT_EXPR))
     return NULL;
 
   /* Use the RHS as new_arg0.  */
-  convert_code = gimple_assign_rhs_code (arg0_def_stmt);
+  op_code = gimple_assign_rhs_code (arg0_def_stmt);
   new_arg0 = gimple_assign_rhs1 (arg0_def_stmt);
-  if (convert_code == VIEW_CONVERT_EXPR)
+  if (op_code == VIEW_CONVERT_EXPR)
     {
       new_arg0 = TREE_OPERAND (new_arg0, 0);
       if (!is_gimple_reg_type (TREE_TYPE (new_arg0)))
@@ -267,10 +269,10 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
   if (TREE_CODE (arg1) == SSA_NAME)
     {
       /* Check if arg1 is an SSA_NAME and the stmt which defines arg1
-	 is a conversion.  */
+	 is an unary operation.  */
       arg1_def_stmt = SSA_NAME_DEF_STMT (arg1);
-      if (!is_gimple_assign (arg1_def_stmt)
-	  || gimple_assign_rhs_code (arg1_def_stmt) != convert_code)
+       if (!is_gimple_assign (arg1_def_stmt)
+	   || gimple_assign_rhs_code (arg1_def_stmt) != op_code)
 	return NULL;
 
       /* Either arg1_def_stmt or arg0_def_stmt should be conditional.  */
@@ -281,7 +283,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
 
       /* Use the RHS as new_arg1.  */
       new_arg1 = gimple_assign_rhs1 (arg1_def_stmt);
-      if (convert_code == VIEW_CONVERT_EXPR)
+      if (op_code == VIEW_CONVERT_EXPR)
 	new_arg1 = TREE_OPERAND (new_arg1, 0);
       if (TREE_CODE (new_arg1) == SSA_NAME
 	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_arg1))
@@ -289,6 +291,10 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
     }
   else
     {
+      /* TODO: handle more than just casts here. */
+      if (!gimple_assign_cast_p (arg0_def_stmt))
+	return NULL;
+
       /* arg0_def_stmt should be conditional.  */
       if (dominated_by_p (CDI_DOMINATORS, gimple_bb (phi), gimple_bb (arg0_def_stmt)))
 	return NULL;
@@ -366,13 +372,13 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
       fprintf (dump_file, "PHI ");
       print_generic_expr (dump_file, gimple_phi_result (phi));
       fprintf (dump_file,
-	       " changed to factor conversion out from COND_EXPR.\n");
-      fprintf (dump_file, "New stmt with CAST that defines ");
+	       " changed to factor operation out from COND_EXPR.\n");
+      fprintf (dump_file, "New stmt with OPERATION that defines ");
       print_generic_expr (dump_file, result);
       fprintf (dump_file, ".\n");
     }
 
-  /* Remove the old cast(s) that has single use.  */
+  /* Remove the old operation(s) that has single use.  */
   gsi_for_def = gsi_for_stmt (arg0_def_stmt);
   gsi_remove (&gsi_for_def, true);
   release_defs (arg0_def_stmt);
@@ -387,14 +393,14 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
   add_phi_arg (newphi, new_arg0, e0, locus);
   add_phi_arg (newphi, new_arg1, e1, locus);
 
-  /* Create the conversion stmt and insert it.  */
-  if (convert_code == VIEW_CONVERT_EXPR)
+  /* Create the operation stmt and insert it.  */
+  if (op_code == VIEW_CONVERT_EXPR)
     {
       temp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), temp);
       new_stmt = gimple_build_assign (result, temp);
     }
   else
-    new_stmt = gimple_build_assign (result, convert_code, temp);
+    new_stmt = gimple_build_assign (result, op_code, temp);
   gsi = gsi_after_labels (gimple_bb (phi));
   gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
 
@@ -402,7 +408,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
   gsi = gsi_for_stmt (phi);
   gsi_remove (&gsi, true);
 
-  statistics_counter_event (cfun, "factored out cast", 1);
+  statistics_counter_event (cfun, "factored out operation", 1);
 
   return newphi;
 }
@@ -3847,11 +3853,11 @@ gate_hoist_loads (void)
    This pass also performs a fifth transformation of a slightly different
    flavor.
 
-   Factor conversion in COND_EXPR
+   Factor operations in COND_EXPR
    ------------------------------
 
-   This transformation factors the conversion out of COND_EXPR with
-   factor_out_conditional_conversion.
+   This transformation factors the unary operations out of COND_EXPR with
+   factor_out_conditional_operation.
 
    For example:
    if (a <= CST) goto <bb 3>; else goto <bb 4>;
@@ -4092,15 +4098,15 @@ pass_phiopt::execute (function *)
 	  while (newphi)
 	    {
 	      phi = newphi;
-	      /* factor_out_conditional_conversion may create a new PHI in
+	      /* factor_out_conditional_operation may create a new PHI in
 		 BB2 and eliminate an existing PHI in BB2.  Recompute values
 		 that may be affected by that change.  */
 	      arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
 	      arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
 	      gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
-	      newphi = factor_out_conditional_conversion (e1, e2, phi,
-							  arg0, arg1,
-							  cond_stmt);
+	      newphi = factor_out_conditional_operation (e1, e2, phi,
+							 arg0, arg1,
+							 cond_stmt);
 	    }
 	}