On 05/23/2016 05:15 PM, Kyrill Tkachov wrote:
> 
> expand_simple_binop may fail. I think you should add a check that diff_rtx is
> non-NULL
> and bail out early if it is.
> 
Fixed.

-- 
Regards,
    Mikhail Maltsev
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index a9c146b..e1473eb 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1260,6 +1260,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
   {
     ST_ADD_FLAG,
     ST_SHIFT_FLAG,
+    ST_SHIFT_ADD_FLAG,
     ST_IOR_FLAG
   };
 
@@ -1384,6 +1385,12 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
 	  normalize = -1;
 	  reversep = true;
 	}
+      else if (exact_log2 (abs_hwi (diff)) >= 0
+	       && (STORE_FLAG_VALUE == 1 || if_info->branch_cost >= 2))
+	{
+	  strategy = ST_SHIFT_ADD_FLAG;
+	  normalize = 1;
+	}
       else
 	return FALSE;
 
@@ -1453,6 +1460,24 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
 					gen_int_mode (ifalse, mode), if_info->x,
 					0, OPTAB_WIDEN);
 	  break;
+	case ST_SHIFT_ADD_FLAG:
+	  {
+	    /* if (test) x = 5; else x = 1;
+	       =>   x = (test != 0) << 2 + 1;  */
+	    HOST_WIDE_INT diff_log = exact_log2 (abs_hwi (diff));
+	    rtx diff_rtx
+	      = expand_simple_binop (mode, ASHIFT, target, GEN_INT (diff_log),
+				     if_info->x, 0, OPTAB_WIDEN);
+	    if (!diff_rtx)
+	      {
+		end_sequence ();
+		return false;
+	      }
+	    target = expand_simple_binop (mode, (diff < 0) ? MINUS : PLUS,
+					  gen_int_mode (ifalse, mode), diff_rtx,
+					  if_info->x, 0, OPTAB_WIDEN);
+	    break;
+	  }
 	}
 
       if (! target)
diff --git a/gcc/testsuite/gcc.dg/ifcvt-6.c b/gcc/testsuite/gcc.dg/ifcvt-6.c
new file mode 100644
index 0000000..c2cfb17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ifcvt-6.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-ce1 -O2" } */
+
+int
+test1 (int a)
+{
+  return a % 2 != 0 ? 7 : 3;
+}
+
+/* { dg-final { scan-rtl-dump "3 true changes made" "ce1" } } */
+/* { dg-final { scan-assembler-not "sbbl" } } */

Reply via email to