diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 05e666e0588..402f8cbd969 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1541,9 +1541,10 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
    in ARG is filled in with constant values.  ARG can either be an aggregate
    expression or a pointer to an aggregate.  ARG_TYPE is the type of the
    aggregate.  JFUNC is the jump function into which the constants are
-   subsequently stored.  */
+   subsequently stored.  Return true if any known aggregate value has been
+   discovered.  */
 
-static void
+static bool
 determine_locally_known_aggregate_parts (gcall *call, tree arg,
 					 tree arg_type,
 					 struct ipa_jump_func *jfunc)
@@ -1557,7 +1558,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
   ao_ref r;
 
   if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0)
-    return;
+    return false;
 
   /* The function operates in three stages.  First, we prepare check_ref, r,
      arg_base and arg_offset based on what is actually passed as an actual
@@ -1571,7 +1572,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
 	  tree type_size;
           if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
 	      || !POINTER_TYPE_P (TREE_TYPE (arg)))
-            return;
+            return false;
 	  check_ref = true;
 	  arg_base = arg;
 	  arg_offset = 0;
@@ -1587,17 +1588,17 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
 	  arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
 						  &arg_size, &reverse);
 	  if (!arg_base)
-	    return;
+	    return false;
 	  if (DECL_P (arg_base))
 	    {
 	      check_ref = false;
 	      ao_ref_init (&r, arg_base);
 	    }
 	  else
-	    return;
+	    return false;
 	}
       else
-	return;
+	return false;
     }
   else
     {
@@ -1610,7 +1611,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
       arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
 					      &arg_size, &reverse);
       if (!arg_base)
-	return;
+	return false;
 
       ao_ref_init (&r, arg);
     }
@@ -1697,7 +1698,9 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
     {
       jfunc->agg.by_ref = by_ref;
       build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
+      return true;
     }
+  return false;
 }
 
 /* Return the Ith param type of callee associated with call graph
@@ -1827,18 +1830,24 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
   struct ipa_edge_args *args = IPA_EDGE_REF (cs);
   gcall *call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
+  bool useful_value = false;
   bool useful_context = false;
 
-  if (arg_num == 0 || args->jump_functions)
+  if (arg_num == 0
+      || gimple_call_internal_p (call)
+      || ipa_func_spec_opts_forbid_analysis_p (cs->caller))
     return;
-  vec_safe_grow_cleared (args->jump_functions, arg_num);
-  if (flag_devirtualize)
-    vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num);
+  gcc_checking_assert (!args->jump_functions
+		       && !args->polymorphic_call_contexts);
 
-  if (gimple_call_internal_p (call))
-    return;
-  if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
-    return;
+  vec_safe_reserve_exact (args->jump_functions, arg_num);
+  args->jump_functions->quick_grow_cleared (arg_num);
+
+  if (flag_devirtualize)
+    {
+      vec_safe_reserve_exact (args->polymorphic_call_contexts, arg_num);
+      vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num);
+    }
 
   for (n = 0; n < arg_num; n++)
     {
@@ -1873,6 +1882,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    {
 	      tree z = build_int_cst (TREE_TYPE (arg), 0);
 	      ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
+	      useful_value = true;
 	    }
 	  else
 	    gcc_assert (!jfunc->m_vr);
@@ -1893,7 +1903,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type,
 					     &tmpvr, TREE_TYPE (arg));
 	      if (!resvr.undefined_p () && !resvr.varying_p ())
-		ipa_set_jfunc_vr (jfunc, &resvr);
+		{
+		  ipa_set_jfunc_vr (jfunc, &resvr);
+		  useful_value = true;
+		}
 	      else
 		gcc_assert (!jfunc->m_vr);
 	    }
@@ -1905,11 +1918,20 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	  && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
 	{
 	  if (TREE_CODE (arg) == SSA_NAME)
-	    ipa_set_jfunc_bits (jfunc, 0,
-				widest_int::from (get_nonzero_bits (arg),
-						  TYPE_SIGN (TREE_TYPE (arg))));
+	    {
+	      widest_int nonzero_bits
+		= widest_int::from (get_nonzero_bits (arg),
+				    TYPE_SIGN (TREE_TYPE (arg)));
+	      ipa_set_jfunc_bits (jfunc, 0, nonzero_bits);
+	      if (SSA_NAME_RANGE_INFO (arg)
+		  && nonzero_bits != -1)
+		useful_value = true;
+	    }
 	  else
-	    ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
+	    {
+	      ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
+	      useful_value = true;
+	    }
 	}
       else if (POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
@@ -1917,6 +1939,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	  unsigned align;
 
 	  get_pointer_alignment_1 (arg, &align, &bitpos);
+	  if (align != BITS_PER_UNIT)
+	    useful_value = true;
 	  widest_int mask = wi::bit_and_not
 	    (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
 	     align / BITS_PER_UNIT - 1);
@@ -1930,7 +1954,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	  || (VAR_P (arg)
 	      && is_global_var (arg)
 	      && TREE_READONLY (arg)))
-	ipa_set_jf_constant (jfunc, arg, cs);
+	{
+	  ipa_set_jf_constant (jfunc, arg, cs);
+	  useful_value = true;
+	}
       else if (!is_gimple_reg_type (TREE_TYPE (arg))
 	       && TREE_CODE (arg) == PARM_DECL)
 	{
@@ -1943,6 +1970,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	  if (parm_preserved_before_stmt_p (fbi, index, call, arg))
 	    {
 	      ipa_set_jf_simple_pass_through (jfunc, index, false);
+	      useful_value = true;
 	      continue;
 	    }
 	}
@@ -1956,6 +1984,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 		  bool agg_p;
 		  agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
 		  ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
+		  useful_value = true;
 		}
 	    }
 	  else
@@ -1969,14 +1998,17 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 						    call,
 						    as_a <gphi *> (stmt));
 	    }
+	  if (jfunc->type != IPA_JF_UNKNOWN)
+	    useful_value = true;
 	}
 
-      /* If ARG is pointer, we can not use its type to determine the type of aggregate
-	 passed (because type conversions are ignored in gimple).  Usually we can
-	 safely get type from function declaration, but in case of K&R prototypes or
-	 variadic functions we can try our luck with type of the pointer passed.
-	 TODO: Since we look for actual initialization of the memory object, we may better
-	 work out the type based on the memory stores we find.  */
+      /* If ARG is pointer, we can not use its type to determine the type of
+	 aggregate passed (because type conversions are ignored in gimple).
+	 Usually we can safely get type from function declaration, but in case
+	 of K&R prototypes or variadic functions we can try our luck with type
+	 of the pointer passed.
+	 TODO: Since we look for actual initialization of the memory object, we
+	 may better work out the type based on the memory stores we find.  */
       if (!param_type)
 	param_type = TREE_TYPE (arg);
 
@@ -1986,8 +2018,16 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      || !ipa_get_jf_ancestor_agg_preserved (jfunc))
 	  && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
 	      || POINTER_TYPE_P (param_type)))
-	determine_locally_known_aggregate_parts (call, arg, param_type, jfunc);
+	{
+	  if (determine_locally_known_aggregate_parts (call, arg, param_type,
+						       jfunc))
+	    useful_value = true;
+	}
     }
+
+  if (!useful_value)
+    vec_free (args->jump_functions);
+
   if (!useful_context)
     vec_free (args->polymorphic_call_contexts);
 }
