ICE at -O1 and above in both 32-bit and 64-bit modes on x86_64-linux-gnu

Message ID b16d3da6-2535-2533-11db-09e7b2c74022@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah Sept. 24, 2016, 3:36 a.m.
Hi Richard,

There is also one more issue as reported by Pat Haugen. That is, in 
converting value_range of ssa  (which we get from get_range_info) to 
argument type, my implementation is too simplistic and wrong at times. I 
can check TYPE_UNSIGNED here but that would be pessimistic.

tree-vrp already has logic to handle this so the attached patch exports 
this and uses it.

This also would be useful when we pass an argument of the function to 
anther function call with unary operation. I will send a separate patch 
for that later if this is OK.

Bootstrapped and regression tested on x86_64-linux-gnu with no new 
regressions. Is this OK for trunk?

Thanks,
Kugan

gcc/ChangeLog:

2016-09-24  Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR ipa/77677
	* ipa-prop.c (ipa_compute_jump_functions_for_edge): Use
	extract_range_from_unary_expr to convert value_range.
	* tree-vrp.c (extract_range_from_unary_expr_1): Rename to.
	(extract_range_from_unary_expr): This.
	* tree-vrp.h (extract_range_from_unary_expr): Declare.

gcc/testsuite/ChangeLog:

2016-09-24  Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR ipa/77677
	* gcc.dg/torture/pr77677-2.c: New test.

Patch hide | download patch | download mbox

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index feecd23..f1f641b 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1703,13 +1703,22 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	  if (TREE_CODE (arg) == SSA_NAME
 	      && param_type
 	      && (type = get_range_info (arg, &min, &max))
-	      && (type == VR_RANGE || type == VR_ANTI_RANGE)
-	      && (min.get_precision () <= TYPE_PRECISION (param_type)))
+	      && (type == VR_RANGE || type == VR_ANTI_RANGE))
 	    {
-	      jfunc->vr_known = true;
-	      jfunc->m_vr.type = type;
-	      jfunc->m_vr.min = wide_int_to_tree (param_type, min);
-	      jfunc->m_vr.max = wide_int_to_tree (param_type, max);
+	      value_range vr;
+
+	      vr.type = type;
+	      vr.min = wide_int_to_tree (TREE_TYPE (arg), min);
+	      vr.max = wide_int_to_tree (TREE_TYPE (arg), max);
+	      vr.equiv = NULL;
+	      extract_range_from_unary_expr_range (&jfunc->m_vr,
+						   NOP_EXPR,
+						   param_type,
+						   &vr, TREE_TYPE (arg));
+	      if (jfunc->m_vr.type == VR_RANGE || jfunc->m_vr.type == VR_ANTI_RANGE)
+		jfunc->vr_known = true;
+	      else
+		jfunc->vr_known = false;
 	    }
 	  else
 	    gcc_assert (!jfunc->vr_known);
diff --git a/gcc/testsuite/gcc.dg/torture/pr77677-2.c b/gcc/testsuite/gcc.dg/torture/pr77677-2.c
index e69de29..661e6a3 100644
--- a/gcc/testsuite/gcc.dg/torture/pr77677-2.c
+++ b/gcc/testsuite/gcc.dg/torture/pr77677-2.c
@@ -0,0 +1,16 @@ 
+/* PR ipa/77677 */
+/* { dg-do compile } */
+
+enum machine_mode { MAX_MACHINE_MODE };
+
+struct {
+  int mode : 8;
+} a;
+int b;
+
+static int fn1();
+
+void fn2() { fn1(a, a.mode); }
+
+int fn1(a, mode) enum machine_mode mode;
+{ int c = b = c; }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 3c75a0d..39a33ae 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3281,10 +3281,10 @@  extract_range_from_binary_expr (value_range *vr,
    the range of its operand *VR0 with type OP0_TYPE with resulting type TYPE.
    The resulting range is stored in *VR.  */
 
-static void
-extract_range_from_unary_expr_1 (value_range *vr,
-				 enum tree_code code, tree type,
-				 value_range *vr0_, tree op0_type)
+void
+extract_range_from_unary_expr_range (value_range *vr,
+				     enum tree_code code, tree type,
+				     value_range *vr0_, tree op0_type)
 {
   value_range vr0 = *vr0_, vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER;
 
@@ -3337,12 +3337,12 @@  extract_range_from_unary_expr_1 (value_range *vr,
   if (vr0.type == VR_ANTI_RANGE
       && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
     {
-      extract_range_from_unary_expr_1 (vr, code, type, &vrtem0, op0_type);
+      extract_range_from_unary_expr_range (vr, code, type, &vrtem0, op0_type);
       if (vrtem1.type != VR_UNDEFINED)
 	{
 	  value_range vrres = VR_INITIALIZER;
-	  extract_range_from_unary_expr_1 (&vrres, code, type,
-					   &vrtem1, op0_type);
+	  extract_range_from_unary_expr_range (&vrres, code, type,
+					       &vrtem1, op0_type);
 	  vrp_meet (vr, &vrres);
 	}
       return;
@@ -3597,7 +3597,7 @@  extract_range_from_unary_expr (value_range *vr, enum tree_code code,
   else
     set_value_range_to_varying (&vr0);
 
-  extract_range_from_unary_expr_1 (vr, code, type, &vr0, TREE_TYPE (op0));
+  extract_range_from_unary_expr_range (vr, code, type, &vr0, TREE_TYPE (op0));
 }
 
 
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index 7ffb7e7..ee92b58 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -51,4 +51,9 @@  struct GTY(()) value_range
 extern void vrp_intersect_ranges (value_range *vr0, value_range *vr1);
 extern void vrp_meet (value_range *vr0, const value_range *vr1);
 extern void dump_value_range (FILE *, const value_range *);
+extern void extract_range_from_unary_expr_range (value_range *vr,
+						 enum tree_code code,
+						 tree type,
+						 value_range *vr0_,
+						 tree op0_type);