[gcc r11-7278] middle-end/99122 - Issues with VLA parameter inlining
Richard Biener
rguenth@gcc.gnu.org
Thu Feb 18 13:38:43 GMT 2021
https://gcc.gnu.org/g:7ee164dcfe390fc030028db9112d44255637b1aa
commit r11-7278-g7ee164dcfe390fc030028db9112d44255637b1aa
Author: Richard Biener <rguenther@suse.de>
Date: Thu Feb 18 12:28:26 2021 +0100
middle-end/99122 - Issues with VLA parameter inlining
The following instructs IPA not to inline calls with VLA parameters
and adjusts inlining not to create invalid view-converted VLA
parameters on mismatch and makes the error_mark paths with debug
stmts actually work.
The first part avoids the ICEs with the testcases already.
2021-02-18 Richard Biener <rguenther@suse.de>
PR middle-end/99122
* ipa-fnsummary.c (analyze_function_body): Set
CIF_FUNCTION_NOT_INLINABLE for VLA parameter calls.
* tree-inline.c (insert_init_debug_bind): Pass NULL for
error_mark_node values.
(force_value_to_type): Do not build V_C_Es for WITH_SIZE_EXPR
values.
(setup_one_parameter): Delay force_value_to_type until when
it's needed.
* gcc.dg/pr99122-1.c: New testcase.
* gcc.dg/pr99122-2.c: Likewise.
Diff:
---
gcc/ipa-fnsummary.c | 8 +++++++-
gcc/testsuite/gcc.dg/pr99122-1.c | 13 +++++++++++++
gcc/testsuite/gcc.dg/pr99122-2.c | 21 +++++++++++++++++++++
gcc/tree-inline.c | 21 +++++++++++++--------
4 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index e32e69cd3ad..c3a25c52214 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2775,7 +2775,13 @@ analyze_function_body (struct cgraph_node *node, bool early)
(gimple_call_arg (stmt, i));
}
}
-
+ /* We cannot setup VLA parameters during inlining. */
+ for (unsigned int i = 0; i < gimple_call_num_args (stmt); ++i)
+ if (TREE_CODE (gimple_call_arg (stmt, i)) == WITH_SIZE_EXPR)
+ {
+ edge->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
+ break;
+ }
es->call_stmt_size = this_size;
es->call_stmt_time = this_time;
es->loop_depth = bb_loop_depth (bb);
diff --git a/gcc/testsuite/gcc.dg/pr99122-1.c b/gcc/testsuite/gcc.dg/pr99122-1.c
new file mode 100644
index 00000000000..5dfc0a85ad4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr99122-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -w" } */
+
+void f ()
+{
+ int n = 5;
+ struct { char a[n]; } x;
+ g (x, x);
+}
+int g (double x, double y)
+{
+ return __builtin_isgreater (x, y);
+}
diff --git a/gcc/testsuite/gcc.dg/pr99122-2.c b/gcc/testsuite/gcc.dg/pr99122-2.c
new file mode 100644
index 00000000000..2b105428233
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr99122-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -w" } */
+
+static int foo ();
+
+int
+bar (int n)
+{
+ struct S { char a[n]; } x;
+ __builtin_memset (x.a, 0, n);
+ return foo (n, x);
+}
+
+static inline int
+foo (int n, struct T { char a[n]; } b)
+{
+ int r = 0, i;
+ for (i = 0; i < n; i++)
+ r += b.a[i];
+ return r;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a710fa59027..01a08cf27be 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3352,7 +3352,10 @@ insert_init_debug_bind (copy_body_data *id,
base_stmt = gsi_stmt (gsi);
}
- note = gimple_build_debug_bind (tracked_var, unshare_expr (value), base_stmt);
+ note = gimple_build_debug_bind (tracked_var,
+ value == error_mark_node
+ ? NULL_TREE : unshare_expr (value),
+ base_stmt);
if (bb)
{
@@ -3418,7 +3421,9 @@ force_value_to_type (tree type, tree value)
Still if we end up with truly mismatched types here, fall back
to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid
GIMPLE to the following passes. */
- if (!is_gimple_reg_type (TREE_TYPE (value))
+ if (TREE_CODE (value) == WITH_SIZE_EXPR)
+ return error_mark_node;
+ else if (!is_gimple_reg_type (TREE_TYPE (value))
|| TYPE_SIZE (type) == TYPE_SIZE (TREE_TYPE (value)))
return fold_build1 (VIEW_CONVERT_EXPR, type, value);
else
@@ -3434,15 +3439,9 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
{
gimple *init_stmt = NULL;
tree var;
- tree rhs = value;
tree def = (gimple_in_ssa_p (cfun)
? ssa_default_def (id->src_cfun, p) : NULL);
- if (value
- && value != error_mark_node
- && !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)))
- rhs = force_value_to_type (TREE_TYPE (p), value);
-
/* Make an equivalent VAR_DECL. Note that we must NOT remap the type
here since the type of this decl must be visible to the calling
function. */
@@ -3501,6 +3500,12 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
TREE_READONLY (var) = 0;
+ tree rhs = value;
+ if (value
+ && value != error_mark_node
+ && !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)))
+ rhs = force_value_to_type (TREE_TYPE (p), value);
+
/* If there is no setup required and we are in SSA, take the easy route
replacing all SSA names representing the function parameter by the
SSA name passed to function.
More information about the Gcc-cvs
mailing list