Hi! The following testcase ICEs because we get: (call_insn/u 7 4 14 2 (set (reg:QI 0 ax) (call (mem:QI (symbol_ref:DI ("_Zlt1AS_") [flags 0x3] <function_decl 0x7efd00f7fc00 operator<>) [0 operator< S1 A8]) (const_int 0 [0]))) 690 {*call_value} (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)) (expr_list:QI (use (mem:QI (reg/f:DI 7 sp) [0 S1 A64])) (expr_list:QI (use (mem:QI (reg/f:DI 7 sp) [0 S1 A64])) (nil)))) where the CALL_INSN_FUNCTION_USAGE USEs for the two empty arguments have size 1 and overlap. In the PR I've added a patch that makes sure the MEMs have BLKmode and zero size, but actually I fail to see any advantages in having anything for the TYPE_EMPTY_P arguments in C_I_F_U, because we actually don't store anything at all, and furthermore I don't see even the need to actually create the MEMs for stack and stack_slot fields etc.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-12-19 Jakub Jelinek <ja...@redhat.com> PR c++/83490 * calls.c (compute_argument_addresses): Ignore TYPE_EMPTY_P arguments. * g++.dg/abi/empty29.C: New test. --- gcc/calls.c.jj 2017-12-18 14:57:24.000000000 +0100 +++ gcc/calls.c 2017-12-19 20:25:00.143659975 +0100 @@ -2365,6 +2365,9 @@ compute_argument_addresses (struct arg_d && args[i].partial == 0) continue; + if (TYPE_EMPTY_P (TREE_TYPE (args[i].tree_value))) + continue; + /* Pointer Bounds are never passed on the stack. */ if (POINTER_BOUNDS_P (args[i].tree_value)) continue; --- gcc/testsuite/g++.dg/abi/empty29.C.jj 2017-12-19 20:46:48.141253484 +0100 +++ gcc/testsuite/g++.dg/abi/empty29.C 2017-12-19 20:47:05.043041447 +0100 @@ -0,0 +1,7 @@ +// PR c++/83490 +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-options "-fipa-icf-functions -Og -maccumulate-outgoing-args" } + +struct A {}; +A operator < (A, A) { return A (); } +A operator > (A, A) { return A (); } Jakub