Hi, PR 91853 and its duplicate PR 91894 show that IPA-SRA can stumble when presented with code with mismatched types, whether because it is a K&R C or happening through an originally indirect call (or probably also because of LTO).
The problem is that we try to work with a register value - in this case an integer constant - like if it was a pointer to a structure and try to dereference it in the caller, leading to expressions like ADDR_EXPR of a constant zero. Old IPA-SRA dealt with these simply by checking type compatibility which is difficult in an LTO-capable IPA pass, basically we would at least have to remember and stream a bitmap for each call telling which arguments are pointers which looks a bit excessive given that we just don't want to ICE. So this patch attempts to deal with the situation rather than avoid it. When an integer is used instead of a pointer, there is some chance that it actually contains the pointer value and so I create a NOP_EXPR to convert it to a pointer (which in the testcase is actually a widening conversion). For other register types, I don't bother and simply pull an undefined pointer default definition SSA name and use that. I wonder whether I should somehow warn as well. Hopefully there is no code doing that that can conceivably work - maybe someone coding for x86_16 and passing a vector of integers as a segment and offset pointer? :-) What do people think? In any event, this patch passed bootstrap and testing and deals with the issue, so if it is OK, I'd like to commit it to trunk. Martin 2019-09-23 Martin Jambor <mjam...@suse.cz> PR ipa/91853 * ipa-param-manipulation.c (ipa_param_adjustments::modify_call): Deal with register type mismatches. testsuite/ * gcc.dg/ipa/pr91853.c: New test. --- gcc/ipa-param-manipulation.c | 22 ++++++++++++++++++++-- gcc/testsuite/gcc.dg/ipa/pr91853.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr91853.c diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c index 913b96fefa4..bc175a5541a 100644 --- a/gcc/ipa-param-manipulation.c +++ b/gcc/ipa-param-manipulation.c @@ -651,8 +651,26 @@ ipa_param_adjustments::modify_call (gcall *stmt, bool deref_base = false; unsigned int deref_align = 0; if (TREE_CODE (base) != ADDR_EXPR - && POINTER_TYPE_P (TREE_TYPE (base))) - off = build_int_cst (apm->alias_ptr_type, apm->unit_offset); + && is_gimple_reg_type (TREE_TYPE (base))) + { + /* Detect (gimple register) type mismatches in calls so that we don't + ICE. Make a poor attempt to gracefully treat integers passed in + place of pointers, for everything else create a proper undefined + value which it is. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (base))) + { + tree tmp = make_ssa_name (ptr_type_node); + gassign *convert = gimple_build_assign (tmp, NOP_EXPR, base); + gsi_insert_before (&gsi, convert, GSI_SAME_STMT); + base = tmp; + } + else if (!POINTER_TYPE_P (TREE_TYPE (base))) + { + tree tmp = create_tmp_var (ptr_type_node); + base = get_or_create_ssa_default_def (cfun, tmp); + } + off = build_int_cst (apm->alias_ptr_type, apm->unit_offset); + } else { bool addrof; diff --git a/gcc/testsuite/gcc.dg/ipa/pr91853.c b/gcc/testsuite/gcc.dg/ipa/pr91853.c new file mode 100644 index 00000000000..4bad7803751 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr91853.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "--param ipa-cp-value-list-size=0 -Os -fno-inline" } */ + +struct _wincore +{ + int y; + int width; +}; +int a; +void fn2 (void); +static int fn1 (dpy, winInfo) struct _XDisplay *dpy; +struct _wincore *winInfo; +{ + a = winInfo->width; + fn2 (); +} + +void fn4 (int, int, int); +static int fn3 (dpy, winInfo, visrgn) struct _XDisplay *dpy; +int winInfo, visrgn; +{ + int b = fn1 (0, winInfo); + fn4 (0, 0, visrgn); +} + +int +fn5 (event) struct _XEvent *event; +{ + fn3 (0, 0, 0); +} -- 2.23.0