aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-03-21 11:42:22 +0000
committerRichard Biener <rguenther@suse.de>2017-03-21 11:42:22 +0000
commitc093dc96f70a4207ab93798da640fa5202268585 (patch)
tree6c14e5dc64408db56178bba818a5fdef94d174eb
parent7c9df3ad7238bc1480d7a78a42dbce60300b4068 (diff)
2017-03-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/80122 * tree-inline.c (copy_bb): Do not expans va-arg packs or va_arg_pack_len when the inlined call stmt requires pack expansion itself. * tree-inline.h (struct copy_body_data): Make call_stmt a gcall *. * gcc.dg/torture/pr80122.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@246313 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr80122.c52
-rw-r--r--gcc/tree-inline.c8
-rw-r--r--gcc/tree-inline.h2
5 files changed, 71 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62c63c46a08..f48f6d39aac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2017-03-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/80122
+ * tree-inline.c (copy_bb): Do not expans va-arg packs or
+ va_arg_pack_len when the inlined call stmt requires pack
+ expansion itself.
+ * tree-inline.h (struct copy_body_data): Make call_stmt a gcall *.
+
2017-03-21 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/78158
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eaf6331dabb..68705a7de06 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/80122
+ * gcc.dg/torture/pr80122.c: New testcase.
+
2017-03-21 Toma Tabacu <toma.tabacu@imgtec.com>
* gcc.dg/pic-2.c: Skip for MIPS.
diff --git a/gcc/testsuite/gcc.dg/torture/pr80122.c b/gcc/testsuite/gcc.dg/torture/pr80122.c
new file mode 100644
index 00000000000..a76d756c32e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr80122.c
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#define __GNU_ALWAYS_INLINE inline __attribute__(( __always_inline__))
+
+#define DEVT_ALL 0
+
+#define CMD_ABI_DEVICES 100
+
+static __GNU_ALWAYS_INLINE int
+send_msg_to_gm_w_dev_t(int msg_type, unsigned int dev_msg_type,
+ int devt, ...)
+{
+ char s[256];
+ int nArgs = __builtin_va_arg_pack_len();
+ if (nArgs != 2)
+ __builtin_abort ();
+ __builtin_sprintf (s, "%d", __builtin_va_arg_pack ());
+ if (__builtin_strcmp (s, "99") != 0)
+ __builtin_abort ();
+ /* do something with nArgs and ... */
+ return 0;
+}
+
+static __GNU_ALWAYS_INLINE int
+send_msg_to_gm(int msg_type, unsigned int dev_msg_type,
+ ...)
+{
+ int nArgs = __builtin_va_arg_pack_len();
+ if (nArgs != 2)
+ __builtin_abort ();
+ return send_msg_to_gm_w_dev_t(msg_type, dev_msg_type,
+ DEVT_ALL, __builtin_va_arg_pack());
+}
+
+static __GNU_ALWAYS_INLINE int
+send_enable(unsigned int dev_msg_type, ...)
+{
+ int nArgs = __builtin_va_arg_pack_len();
+ if (nArgs != 2)
+ __builtin_abort ();
+ return send_msg_to_gm(CMD_ABI_DEVICES, dev_msg_type, __builtin_va_arg_pack());
+}
+
+int
+main(void)
+{
+ int mode = 99;
+
+ send_enable(1, mode, sizeof(mode));
+
+ return 0;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index bd4b48e8623..6b6d489f6ca 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1860,7 +1860,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
call_stmt = dyn_cast <gcall *> (stmt);
if (call_stmt
&& gimple_call_va_arg_pack_p (call_stmt)
- && id->call_stmt)
+ && id->call_stmt
+ && ! gimple_call_va_arg_pack_p (id->call_stmt))
{
/* __builtin_va_arg_pack () should be replaced by
all arguments corresponding to ... in the caller. */
@@ -1940,7 +1941,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
&& id->call_stmt
&& (decl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN
+ && ! gimple_call_va_arg_pack_p (id->call_stmt))
{
/* __builtin_va_arg_pack_len () should be replaced by
the number of anonymous arguments. */
@@ -4584,7 +4586,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
/* Record the function we are about to inline. */
id->src_fn = fn;
id->src_cfun = DECL_STRUCT_FUNCTION (fn);
- id->call_stmt = stmt;
+ id->call_stmt = call_stmt;
/* If the src function contains an IFN_VA_ARG, then so will the dst
function after inlining. Likewise for IFN_GOMP_USE_SIMT. */
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 41402a315ec..88b32863745 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -81,7 +81,7 @@ struct copy_body_data
/* GIMPLE_CALL if va arg parameter packs should be expanded or NULL
is not. */
- gimple *call_stmt;
+ gcall *call_stmt;
/* Exception landing pad the inlined call lies in. */
int eh_lp_nr;