I observed the following when investigating the effect of the introduction of ifn_va_arg for aarch64 on stdarg-1.c. At optimized dump, before introduction of ifn_va_arg we have a single comparison (_4 >= -7): ... foo (int v, struct va_list ap) { int * iftmp.0_1; int _4; void * _5; void * _7; sizetype _8; int * iftmp.1_9; int foo_arg.2_10; <bb 2>: switch (v_2(D)) <default: <L7>, case 5: <L0>> <L0>: _4 = ap.__gr_offs; _5 = ap.__stack; if (_4 >= -7) goto <bb 5>; else goto <bb 4>; <bb 4>: _7 = ap.__gr_top; _8 = (sizetype) _4; iftmp.1_9 = _7 + _8; <bb 5>: # iftmp.0_1 = PHI <_5(3), iftmp.1_9(4)> foo_arg.2_10 = *iftmp.0_1; foo_arg = foo_arg.2_10; return; <L7>: abort (); } ... After introduction of ifn_va_arg, we have two comparisons (ap$__gr_offs_20 >= 0, ap$__gr_offs_20 >= -7): ... foo (int v, struct va_list ap) { int ap$__gr_offs; void * ap$__stack; int * iftmp.28; int * iftmp.29; void * D.2827; sizetype D.2828; int foo_arg.0_4; <bb 2>: switch (v_1(D)) <default: <L1>, case 5: <L9>> <L9>: ap$__stack_26 = MEM[(struct *)&ap]; ap$__gr_offs_20 = MEM[(struct *)&ap + 24B]; if (ap$__gr_offs_20 >= 0) goto <bb 7>; else goto <bb 4>; <bb 4>: if (ap$__gr_offs_20 >= -7) goto <bb 6>; else goto <bb 5>; <bb 5>: _28 = ap.__gr_top; _29 = (sizetype) ap$__gr_offs_20; iftmp.29_30 = _28 + _29; <bb 6>: # iftmp.29_10 = PHI <ap$__stack_26(4), iftmp.29_30(5)> <bb 7>: # iftmp.28_9 = PHI <ap$__stack_26(3), iftmp.29_10(6)> foo_arg.0_4 = *iftmp.28_9; foo_arg = foo_arg.0_4; return; <L1>: abort (); } ... The tree optimization ifcombine can combine the two comparisons, so: 1. Before the introduction of ifn_va_arg, the va_arg is expanded at gimplification, and ifcombine manages to combine the two comparisons. 2. After the introduction of ifn_va_arg, the va_arg is expanded at pass_starg, a few steps after the ifcombine pass, and the optimization does not happen: ... NEXT_PASS (pass_tree_ifcombine); NEXT_PASS (pass_phiopt); NEXT_PASS (pass_tail_recursion); NEXT_PASS (pass_ch); NEXT_PASS (pass_stdarg); ...
(In reply to vries from comment #0) > I observed the following when investigating the effect of the introduction > of ifn_va_arg for aarch64 on stdarg-1.c. That's ./gcc/testsuite/gcc.c-torture/execute/stdarg-1.c, btw.
IMHO it makes sense to move stdarg a bit earlier, after pass_dce.
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg01835.html
Author: vries Date: Wed Apr 29 09:13:49 2015 New Revision: 222567 URL: https://gcc.gnu.org/viewcvs?rev=222567&root=gcc&view=rev Log: Move pass_stdarg to after pass_dce in pass_all_optimizations 2015-04-29 Tom de Vries <tom@codesourcery.com> PR tree-optimization/65893 * passes.def (pass_all_optimizations): Move pass_stdarg to after pass_dce. Modified: trunk/gcc/ChangeLog trunk/gcc/passes.def
patch committed, marking resolved-fixed.