Message ID | 20241110125550.787007-3-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | Improve outgoing integer argument promotion | expand |
On Sun, Nov 10, 2024 at 1:55 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > Since the C/C++/Ada frontends no longer promote integer argument smaller > than int, add expand_promote_outgoing_argument to promote it when expanding > builtin functions. I wonder if we should instead handle this in the generic builtin expansion code instead? Otherwise we'd need to fix all targets similarly? Richard. > PR middle-end/14907 > * expr.cc (expand_promote_outgoing_argument): New function. > * expr.h (expand_promote_outgoing_argument): New prototype. > * config/i386/i386-expand.cc (ix86_expand_binop_builtin): Call > expand_promote_outgoing_argument to expand the outgoing > argument. > (ix86_expand_multi_arg_builtin): Likewise. > (ix86_expand_unop_vec_merge_builtin): Likewise. > (ix86_expand_sse_compare): Likewise. > (ix86_expand_sse_comi): Likewise. > (ix86_expand_sse_round): Likewise. > (ix86_expand_sse_round_vec_pack_sfix): Likewise. > (ix86_expand_sse_ptest): Likewise. > (ix86_expand_sse_pcmpestr): Likewise. > (ix86_expand_sse_pcmpistr): Likewise. > (ix86_expand_args_builtin): Likewise. > (ix86_expand_sse_comi_round): Likewise. > (ix86_expand_round_builtin): Likewise. > (ix86_expand_special_args_builtin): Likewise. > (ix86_expand_vec_init_builtin): Likewise. > (ix86_expand_vec_ext_builtin): Likewise. > (ix86_expand_builtin): Likewise. > > Signed-off-by: H.J. Lu <hjl.tools@gmail.com> > --- > gcc/config/i386/i386-expand.cc | 244 ++++++++++++++++----------------- > gcc/expr.cc | 18 +++ > gcc/expr.h | 1 + > 3 files changed, 141 insertions(+), 122 deletions(-) > > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc > index 5c4a8e07d62..ce887d96f6a 100644 > --- a/gcc/config/i386/i386-expand.cc > +++ b/gcc/config/i386/i386-expand.cc > @@ -10415,8 +10415,8 @@ ix86_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > tree arg1 = CALL_EXPR_ARG (exp, 1); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > machine_mode tmode = insn_data[icode].operand[0].mode; > machine_mode mode0 = insn_data[icode].operand[1].mode; > machine_mode mode1 = insn_data[icode].operand[2].mode; > @@ -10564,7 +10564,7 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target, > for (i = 0; i < nargs; i++) > { > tree arg = CALL_EXPR_ARG (exp, i); > - rtx op = expand_normal (arg); > + rtx op = expand_promote_outgoing_argument (arg); > int adjust = (comparison_p) ? 1 : 0; > machine_mode mode = insn_data[icode].operand[i+adjust+1].mode; > > @@ -10691,7 +10691,7 @@ ix86_expand_unop_vec_merge_builtin (enum insn_code icode, tree exp, > { > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > - rtx op1, op0 = expand_normal (arg0); > + rtx op1, op0 = expand_promote_outgoing_argument (arg0); > machine_mode tmode = insn_data[icode].operand[0].mode; > machine_mode mode0 = insn_data[icode].operand[1].mode; > > @@ -10727,8 +10727,8 @@ ix86_expand_sse_compare (const struct builtin_description *d, > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > tree arg1 = CALL_EXPR_ARG (exp, 1); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > rtx op2; > machine_mode tmode = insn_data[d->icode].operand[0].mode; > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > @@ -10823,8 +10823,8 @@ ix86_expand_sse_comi (const struct builtin_description *d, tree exp, > rtx pat, set_dst; > tree arg0 = CALL_EXPR_ARG (exp, 0); > tree arg1 = CALL_EXPR_ARG (exp, 1); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > enum insn_code icode = d->icode; > const struct insn_data_d *insn_p = &insn_data[icode]; > machine_mode mode0 = insn_p->operand[0].mode; > @@ -10916,7 +10916,7 @@ ix86_expand_sse_round (const struct builtin_description *d, tree exp, > { > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > - rtx op1, op0 = expand_normal (arg0); > + rtx op1, op0 = expand_promote_outgoing_argument (arg0); > machine_mode tmode = insn_data[d->icode].operand[0].mode; > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > > @@ -10948,8 +10948,8 @@ ix86_expand_sse_round_vec_pack_sfix (const struct builtin_description *d, > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > tree arg1 = CALL_EXPR_ARG (exp, 1); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > rtx op2; > machine_mode tmode = insn_data[d->icode].operand[0].mode; > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > @@ -10988,8 +10988,8 @@ ix86_expand_sse_ptest (const struct builtin_description *d, tree exp, > rtx pat; > tree arg0 = CALL_EXPR_ARG (exp, 0); > tree arg1 = CALL_EXPR_ARG (exp, 1); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > machine_mode mode0 = insn_data[d->icode].operand[0].mode; > machine_mode mode1 = insn_data[d->icode].operand[1].mode; > enum rtx_code comparison = d->comparison; > @@ -11047,11 +11047,11 @@ ix86_expand_sse_pcmpestr (const struct builtin_description *d, > tree arg3 = CALL_EXPR_ARG (exp, 3); > tree arg4 = CALL_EXPR_ARG (exp, 4); > rtx scratch0, scratch1; > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > - rtx op2 = expand_normal (arg2); > - rtx op3 = expand_normal (arg3); > - rtx op4 = expand_normal (arg4); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > + rtx op2 = expand_promote_outgoing_argument (arg2); > + rtx op3 = expand_promote_outgoing_argument (arg3); > + rtx op4 = expand_promote_outgoing_argument (arg4); > machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm; > > tmode0 = insn_data[d->icode].operand[0].mode; > @@ -11150,9 +11150,9 @@ ix86_expand_sse_pcmpistr (const struct builtin_description *d, > tree arg1 = CALL_EXPR_ARG (exp, 1); > tree arg2 = CALL_EXPR_ARG (exp, 2); > rtx scratch0, scratch1; > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > - rtx op2 = expand_normal (arg2); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > + rtx op2 = expand_promote_outgoing_argument (arg2); > machine_mode tmode0, tmode1, modev2, modev3, modeimm; > > tmode0 = insn_data[d->icode].operand[0].mode; > @@ -12135,7 +12135,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, > for (i = 0; i < nargs; i++) > { > tree arg = CALL_EXPR_ARG (exp, i); > - rtx op = expand_normal (arg); > + rtx op = expand_promote_outgoing_argument (arg); > machine_mode mode = insn_p->operand[i + 1].mode; > /* Need to fixup modeless constant before testing predicate. */ > op = fixup_modeless_constant (op, mode); > @@ -12400,10 +12400,10 @@ ix86_expand_sse_comi_round (const struct builtin_description *d, > tree arg1 = CALL_EXPR_ARG (exp, 1); > tree arg2 = CALL_EXPR_ARG (exp, 2); > tree arg3 = CALL_EXPR_ARG (exp, 3); > - rtx op0 = expand_normal (arg0); > - rtx op1 = expand_normal (arg1); > - rtx op2 = expand_normal (arg2); > - rtx op3 = expand_normal (arg3); > + rtx op0 = expand_promote_outgoing_argument (arg0); > + rtx op1 = expand_promote_outgoing_argument (arg1); > + rtx op2 = expand_promote_outgoing_argument (arg2); > + rtx op3 = expand_promote_outgoing_argument (arg3); > enum insn_code icode = d->icode; > const struct insn_data_d *insn_p = &insn_data[icode]; > machine_mode mode0 = insn_p->operand[0].mode; > @@ -12870,7 +12870,7 @@ ix86_expand_round_builtin (const struct builtin_description *d, > for (i = 0; i < nargs; i++) > { > tree arg = CALL_EXPR_ARG (exp, i); > - rtx op = expand_normal (arg); > + rtx op = expand_promote_outgoing_argument (arg); > machine_mode mode = insn_p->operand[i + 1].mode; > bool match = insn_p->operand[i + 1].predicate (op, mode); > > @@ -13318,7 +13318,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, > if (klass == store) > { > arg = CALL_EXPR_ARG (exp, 0); > - op = expand_normal (arg); > + op = expand_promote_outgoing_argument (arg); > gcc_assert (target == 0); > if (memory) > { > @@ -13355,7 +13355,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, > machine_mode mode = insn_p->operand[i + 1].mode; > > arg = CALL_EXPR_ARG (exp, i + arg_adjust); > - op = expand_normal (arg); > + op = expand_promote_outgoing_argument (arg); > > if (i == memory) > { > @@ -13479,7 +13479,7 @@ ix86_expand_vec_init_builtin (tree type, tree exp, rtx target) > > for (i = 0; i < n_elt; ++i) > { > - rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); > + rtx x = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, i)); > RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); > } > > @@ -13505,7 +13505,7 @@ ix86_expand_vec_ext_builtin (tree exp, rtx target) > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > elt = get_element_number (TREE_TYPE (arg0), arg1); > > tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); > @@ -13727,9 +13727,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg1 = CALL_EXPR_ARG (exp, 0); > arg2 = CALL_EXPR_ARG (exp, 1); > arg0 = CALL_EXPR_ARG (exp, 2); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > mode0 = insn_data[icode].operand[0].mode; > mode1 = insn_data[icode].operand[1].mode; > mode2 = insn_data[icode].operand[2].mode; > @@ -13750,7 +13750,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > return 0; > > case IX86_BUILTIN_LDMXCSR: > - op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); > + op0 = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, 0)); > target = assign_stack_temp (SImode, GET_MODE_SIZE (SImode)); > emit_move_insn (target, op0); > emit_insn (gen_sse_ldmxcsr (target)); > @@ -13763,7 +13763,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_CLFLUSH: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > icode = CODE_FOR_sse2_clflush; > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > op0 = ix86_zero_extend_to_Pmode (op0); > @@ -13773,7 +13773,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_CLWB: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > icode = CODE_FOR_clwb; > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > op0 = ix86_zero_extend_to_Pmode (op0); > @@ -13783,7 +13783,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_CLFLUSHOPT: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > icode = CODE_FOR_clflushopt; > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > op0 = ix86_zero_extend_to_Pmode (op0); > @@ -13796,9 +13796,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > arg2 = CALL_EXPR_ARG (exp, 2); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > if (!REG_P (op0)) > op0 = ix86_zero_extend_to_Pmode (op0); > if (!REG_P (op1)) > @@ -13814,8 +13814,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_MWAIT: > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > if (!REG_P (op1)) > @@ -13827,9 +13827,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > arg2 = CALL_EXPR_ARG (exp, 2); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > if (!REG_P (op1)) > @@ -13841,7 +13841,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_UMONITOR: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > op0 = ix86_zero_extend_to_Pmode (op0); > emit_insn (gen_umonitor (Pmode, op0)); > @@ -13851,8 +13851,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_TPAUSE: > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > @@ -13925,7 +13925,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_CLZERO: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > if (!REG_P (op0)) > op0 = ix86_zero_extend_to_Pmode (op0); > emit_insn (gen_clzero (Pmode, op0)); > @@ -13933,7 +13933,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_CLDEMOTE: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > icode = CODE_FOR_cldemote; > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > op0 = ix86_zero_extend_to_Pmode (op0); > @@ -13948,10 +13948,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg2 = CALL_EXPR_ARG (exp, 2); > arg3 = CALL_EXPR_ARG (exp, 3); > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > > if (!REG_P (op0)) > op0 = copy_to_mode_reg (V2DImode, op0); > @@ -13988,9 +13988,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg1 = CALL_EXPR_ARG (exp, 1); // __m128i idata > arg2 = CALL_EXPR_ARG (exp, 2); // const void *p > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > > if (!address_operand (op0, V2DImode)) > { > @@ -14060,9 +14060,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg1 = CALL_EXPR_ARG (exp, 1); // const __m128i * idata > arg2 = CALL_EXPR_ARG (exp, 2); // const void *p > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > > if (!address_operand (op2, VOIDmode)) > { > @@ -14116,9 +14116,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg1 = CALL_EXPR_ARG (exp, 1); // __m128i key > arg2 = CALL_EXPR_ARG (exp, 2); // void *h > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > @@ -14152,10 +14152,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg2 = CALL_EXPR_ARG (exp, 2); // __m128i keyhi > arg3 = CALL_EXPR_ARG (exp, 3); // void *h > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > @@ -14191,10 +14191,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg2 = CALL_EXPR_ARG (exp, 2); // const int > arg3 = CALL_EXPR_ARG (exp, 3); // const int > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > > if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P (op3)) > { > @@ -14264,8 +14264,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg0 = CALL_EXPR_ARG (exp, 0); // const void * > arg1 = CALL_EXPR_ARG (exp, 1); // const int > > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > if (!CONST_INT_P (op1)) > { > @@ -14295,7 +14295,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_UWRMSR: > { > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > if (CONST_INT_P (op0)) > { > @@ -14309,7 +14309,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > if (fcode == IX86_BUILTIN_UWRMSR) > { > arg1 = CALL_EXPR_ARG (exp, 1); > - op1 = expand_normal (arg1); > + op1 = expand_promote_outgoing_argument (arg1); > op1 = force_reg (DImode, op1); > icode = CODE_FOR_uwrmsr; > target = 0; > @@ -14384,10 +14384,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg1 = CALL_EXPR_ARG (exp, 1); > arg2 = CALL_EXPR_ARG (exp, 2); > arg3 = CALL_EXPR_ARG (exp, 3); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > > if (!address_operand (op0, VOIDmode)) > { > @@ -14458,7 +14458,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > if (fcode == IX86_BUILTIN_RDPMC) > { > arg0 = CALL_EXPR_ARG (exp, 0); > - op2 = expand_normal (arg0); > + op2 = expand_promote_outgoing_argument (arg0); > if (!register_operand (op2, SImode)) > op2 = copy_to_mode_reg (SImode, op2); > > @@ -14470,7 +14470,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > else if (fcode == IX86_BUILTIN_XGETBV) > { > arg0 = CALL_EXPR_ARG (exp, 0); > - op2 = expand_normal (arg0); > + op2 = expand_promote_outgoing_argument (arg0); > if (!register_operand (op2, SImode)) > op2 = copy_to_mode_reg (SImode, op2); > > @@ -14496,7 +14496,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > emit_insn (insn); > > arg0 = CALL_EXPR_ARG (exp, 0); > - op4 = expand_normal (arg0); > + op4 = expand_promote_outgoing_argument (arg0); > if (!address_operand (op4, VOIDmode)) > { > op4 = convert_memory_address (Pmode, op4); > @@ -14526,8 +14526,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > op0 = ix86_zero_extend_to_Pmode (op0); > if (!address_operand (op1, VOIDmode)) > @@ -14597,7 +14597,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > } > > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > if (!address_operand (op0, VOIDmode)) > { > @@ -14614,8 +14614,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_XSETBV: > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > if (!REG_P (op0)) > op0 = copy_to_mode_reg (SImode, op0); > @@ -14657,8 +14657,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_XSAVEC64: > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > if (!address_operand (op0, VOIDmode)) > { > @@ -14754,7 +14754,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > case IX86_BUILTIN_LDTILECFG: > case IX86_BUILTIN_STTILECFG: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > if (!address_operand (op0, VOIDmode)) > { > @@ -14772,7 +14772,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > case IX86_BUILTIN_LLWPCB: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > if (!register_operand (op0, Pmode)) > op0 = ix86_zero_extend_to_Pmode (op0); > @@ -14803,9 +14803,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > arg2 = CALL_EXPR_ARG (exp, 2); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > mode0 = insn_data[icode].operand[0].mode; > > if (!insn_data[icode].operand[0].predicate (op0, mode0)) > @@ -14843,8 +14843,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > if (!CONST_INT_P (op1)) > { > @@ -14898,7 +14898,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, > > rdrand_step: > arg0 = CALL_EXPR_ARG (exp, 0); > - op1 = expand_normal (arg0); > + op1 = expand_promote_outgoing_argument (arg0); > if (!address_operand (op1, VOIDmode)) > { > op1 = convert_memory_address (Pmode, op1); > @@ -14958,7 +14958,7 @@ rdrand_step: > > rdseed_step: > arg0 = CALL_EXPR_ARG (exp, 0); > - op1 = expand_normal (arg0); > + op1 = expand_promote_outgoing_argument (arg0); > if (!address_operand (op1, VOIDmode)) > { > op1 = convert_memory_address (Pmode, op1); > @@ -15020,17 +15020,17 @@ rdseed_step: > arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2. */ > arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */ > > - op1 = expand_normal (arg0); > + op1 = expand_promote_outgoing_argument (arg0); > > - op2 = expand_normal (arg1); > + op2 = expand_promote_outgoing_argument (arg1); > if (!register_operand (op2, mode0)) > op2 = copy_to_mode_reg (mode0, op2); > > - op3 = expand_normal (arg2); > + op3 = expand_promote_outgoing_argument (arg2); > if (!register_operand (op3, mode0)) > op3 = copy_to_mode_reg (mode0, op3); > > - op4 = expand_normal (arg3); > + op4 = expand_promote_outgoing_argument (arg3); > if (!address_operand (op4, VOIDmode)) > { > op4 = convert_memory_address (Pmode, op4); > @@ -15087,7 +15087,7 @@ rdseed_step: > case IX86_BUILTIN_WRITE_FLAGS: > > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > if (!general_no_elim_operand (op0, word_mode)) > op0 = copy_to_mode_reg (word_mode, op0); > > @@ -15177,8 +15177,8 @@ rdseed_step: > kortest: > arg0 = CALL_EXPR_ARG (exp, 0); /* Mask reg src1. */ > arg1 = CALL_EXPR_ARG (exp, 1); /* Mask reg src2. */ > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > > mode0 = insn_data[icode].operand[0].mode; > mode1 = insn_data[icode].operand[1].mode; > @@ -15482,11 +15482,11 @@ rdseed_step: > arg2 = CALL_EXPR_ARG (exp, 2); > arg3 = CALL_EXPR_ARG (exp, 3); > arg4 = CALL_EXPR_ARG (exp, 4); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > - op4 = expand_normal (arg4); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > + op4 = expand_promote_outgoing_argument (arg4); > /* Note the arg order is different from the operand order. */ > mode0 = insn_data[icode].operand[1].mode; > mode2 = insn_data[icode].operand[3].mode; > @@ -15699,11 +15699,11 @@ rdseed_step: > arg2 = CALL_EXPR_ARG (exp, 2); > arg3 = CALL_EXPR_ARG (exp, 3); > arg4 = CALL_EXPR_ARG (exp, 4); > - op0 = expand_normal (arg0); > - op1 = expand_normal (arg1); > - op2 = expand_normal (arg2); > - op3 = expand_normal (arg3); > - op4 = expand_normal (arg4); > + op0 = expand_promote_outgoing_argument (arg0); > + op1 = expand_promote_outgoing_argument (arg1); > + op2 = expand_promote_outgoing_argument (arg2); > + op3 = expand_promote_outgoing_argument (arg3); > + op4 = expand_promote_outgoing_argument (arg4); > mode1 = insn_data[icode].operand[1].mode; > mode2 = insn_data[icode].operand[2].mode; > mode3 = insn_data[icode].operand[3].mode; > @@ -15812,7 +15812,7 @@ rdseed_step: > case IX86_BUILTIN_XABORT: > icode = CODE_FOR_xabort; > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > mode0 = insn_data[icode].operand[0].mode; > if (!insn_data[icode].operand[0].predicate (op0, mode0)) > { > @@ -15841,7 +15841,7 @@ rdseed_step: > mode = (fcode == IX86_BUILTIN_INCSSPD ? SImode : DImode); > > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > > op0 = force_reg (mode, op0); > > @@ -15851,7 +15851,7 @@ rdseed_step: > case IX86_BUILTIN_HRESET: > icode = CODE_FOR_hreset; > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > op0 = force_reg (SImode, op0); > emit_insn (gen_hreset (op0)); > return 0; > @@ -15859,7 +15859,7 @@ rdseed_step: > case IX86_BUILTIN_RSTORSSP: > case IX86_BUILTIN_CLRSSBSY: > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > icode = (fcode == IX86_BUILTIN_RSTORSSP > ? CODE_FOR_rstorssp > : CODE_FOR_clrssbsy); > @@ -15881,9 +15881,9 @@ rdseed_step: > ? SImode : DImode); > > arg0 = CALL_EXPR_ARG (exp, 0); > - op0 = expand_normal (arg0); > + op0 = expand_promote_outgoing_argument (arg0); > arg1 = CALL_EXPR_ARG (exp, 1); > - op1 = expand_normal (arg1); > + op1 = expand_promote_outgoing_argument (arg1); > > op0 = force_reg (mode, op0); > > diff --git a/gcc/expr.cc b/gcc/expr.cc > index caa1a72ba0b..0a1a70dab3c 100644 > --- a/gcc/expr.cc > +++ b/gcc/expr.cc > @@ -14136,3 +14136,21 @@ int_expr_size (const_tree exp) > > return tree_to_shwi (size); > } > + > +/* Expand an outgoing argument ARG with promotion. Since the C/C++ > + frontends no longer promote integer argument smaller than int, > + promote it when expanding built functions. */ > + > +rtx > +expand_promote_outgoing_argument (tree arg) > +{ > + tree type = TREE_TYPE (arg); > + if (INTEGRAL_TYPE_P (type) > + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) > + { > + tree promoted_type = (TYPE_UNSIGNED (type) > + ? unsigned_type_node : integer_type_node); > + arg = fold_convert (promoted_type, arg); > + } > + return expand_normal (arg); > +} > diff --git a/gcc/expr.h b/gcc/expr.h > index 04782b15f19..ed14750614b 100644 > --- a/gcc/expr.h > +++ b/gcc/expr.h > @@ -312,6 +312,7 @@ extern rtx expand_expr_real_2 (const_sepops, rtx, machine_mode, > extern rtx expand_expr_real_gassign (gassign *, rtx, machine_mode, > enum expand_modifier modifier, > rtx * = nullptr, bool = false); > +extern rtx expand_promote_outgoing_argument (tree); > > /* Generate code for computing expression EXP. > An rtx for the computed value is returned. The value is never null. > -- > 2.47.0 >
On Wed, Nov 20, 2024 at 10:18 PM Richard Biener <richard.guenther@gmail.com> wrote: > On Sun, Nov 10, 2024 at 1:55 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > Since the C/C++/Ada frontends no longer promote integer argument smaller > > than int, add expand_promote_outgoing_argument to promote it when > expanding > > builtin functions. > > I wonder if we should instead handle this in the generic builtin expansion > code > instead? Otherwise we'd need to fix all targets similarly? > This is for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117547 I think it should be fixed differently in the x86 backend. > Richard. > > > PR middle-end/14907 > > * expr.cc (expand_promote_outgoing_argument): New function. > > * expr.h (expand_promote_outgoing_argument): New prototype. > > * config/i386/i386-expand.cc (ix86_expand_binop_builtin): Call > > expand_promote_outgoing_argument to expand the outgoing > > argument. > > (ix86_expand_multi_arg_builtin): Likewise. > > (ix86_expand_unop_vec_merge_builtin): Likewise. > > (ix86_expand_sse_compare): Likewise. > > (ix86_expand_sse_comi): Likewise. > > (ix86_expand_sse_round): Likewise. > > (ix86_expand_sse_round_vec_pack_sfix): Likewise. > > (ix86_expand_sse_ptest): Likewise. > > (ix86_expand_sse_pcmpestr): Likewise. > > (ix86_expand_sse_pcmpistr): Likewise. > > (ix86_expand_args_builtin): Likewise. > > (ix86_expand_sse_comi_round): Likewise. > > (ix86_expand_round_builtin): Likewise. > > (ix86_expand_special_args_builtin): Likewise. > > (ix86_expand_vec_init_builtin): Likewise. > > (ix86_expand_vec_ext_builtin): Likewise. > > (ix86_expand_builtin): Likewise. > > > > Signed-off-by: H.J. Lu <hjl.tools@gmail.com> > > --- > > gcc/config/i386/i386-expand.cc | 244 ++++++++++++++++----------------- > > gcc/expr.cc | 18 +++ > > gcc/expr.h | 1 + > > 3 files changed, 141 insertions(+), 122 deletions(-) > > > > diff --git a/gcc/config/i386/i386-expand.cc > b/gcc/config/i386/i386-expand.cc > > index 5c4a8e07d62..ce887d96f6a 100644 > > --- a/gcc/config/i386/i386-expand.cc > > +++ b/gcc/config/i386/i386-expand.cc > > @@ -10415,8 +10415,8 @@ ix86_expand_binop_builtin (enum insn_code icode, > tree exp, rtx target) > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > machine_mode tmode = insn_data[icode].operand[0].mode; > > machine_mode mode0 = insn_data[icode].operand[1].mode; > > machine_mode mode1 = insn_data[icode].operand[2].mode; > > @@ -10564,7 +10564,7 @@ ix86_expand_multi_arg_builtin (enum insn_code > icode, tree exp, rtx target, > > for (i = 0; i < nargs; i++) > > { > > tree arg = CALL_EXPR_ARG (exp, i); > > - rtx op = expand_normal (arg); > > + rtx op = expand_promote_outgoing_argument (arg); > > int adjust = (comparison_p) ? 1 : 0; > > machine_mode mode = insn_data[icode].operand[i+adjust+1].mode; > > > > @@ -10691,7 +10691,7 @@ ix86_expand_unop_vec_merge_builtin (enum > insn_code icode, tree exp, > > { > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > - rtx op1, op0 = expand_normal (arg0); > > + rtx op1, op0 = expand_promote_outgoing_argument (arg0); > > machine_mode tmode = insn_data[icode].operand[0].mode; > > machine_mode mode0 = insn_data[icode].operand[1].mode; > > > > @@ -10727,8 +10727,8 @@ ix86_expand_sse_compare (const struct > builtin_description *d, > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > rtx op2; > > machine_mode tmode = insn_data[d->icode].operand[0].mode; > > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > > @@ -10823,8 +10823,8 @@ ix86_expand_sse_comi (const struct > builtin_description *d, tree exp, > > rtx pat, set_dst; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > enum insn_code icode = d->icode; > > const struct insn_data_d *insn_p = &insn_data[icode]; > > machine_mode mode0 = insn_p->operand[0].mode; > > @@ -10916,7 +10916,7 @@ ix86_expand_sse_round (const struct > builtin_description *d, tree exp, > > { > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > - rtx op1, op0 = expand_normal (arg0); > > + rtx op1, op0 = expand_promote_outgoing_argument (arg0); > > machine_mode tmode = insn_data[d->icode].operand[0].mode; > > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > > > > @@ -10948,8 +10948,8 @@ ix86_expand_sse_round_vec_pack_sfix (const > struct builtin_description *d, > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > rtx op2; > > machine_mode tmode = insn_data[d->icode].operand[0].mode; > > machine_mode mode0 = insn_data[d->icode].operand[1].mode; > > @@ -10988,8 +10988,8 @@ ix86_expand_sse_ptest (const struct > builtin_description *d, tree exp, > > rtx pat; > > tree arg0 = CALL_EXPR_ARG (exp, 0); > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > machine_mode mode0 = insn_data[d->icode].operand[0].mode; > > machine_mode mode1 = insn_data[d->icode].operand[1].mode; > > enum rtx_code comparison = d->comparison; > > @@ -11047,11 +11047,11 @@ ix86_expand_sse_pcmpestr (const struct > builtin_description *d, > > tree arg3 = CALL_EXPR_ARG (exp, 3); > > tree arg4 = CALL_EXPR_ARG (exp, 4); > > rtx scratch0, scratch1; > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > - rtx op2 = expand_normal (arg2); > > - rtx op3 = expand_normal (arg3); > > - rtx op4 = expand_normal (arg4); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > + rtx op2 = expand_promote_outgoing_argument (arg2); > > + rtx op3 = expand_promote_outgoing_argument (arg3); > > + rtx op4 = expand_promote_outgoing_argument (arg4); > > machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm; > > > > tmode0 = insn_data[d->icode].operand[0].mode; > > @@ -11150,9 +11150,9 @@ ix86_expand_sse_pcmpistr (const struct > builtin_description *d, > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > tree arg2 = CALL_EXPR_ARG (exp, 2); > > rtx scratch0, scratch1; > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > - rtx op2 = expand_normal (arg2); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > + rtx op2 = expand_promote_outgoing_argument (arg2); > > machine_mode tmode0, tmode1, modev2, modev3, modeimm; > > > > tmode0 = insn_data[d->icode].operand[0].mode; > > @@ -12135,7 +12135,7 @@ ix86_expand_args_builtin (const struct > builtin_description *d, > > for (i = 0; i < nargs; i++) > > { > > tree arg = CALL_EXPR_ARG (exp, i); > > - rtx op = expand_normal (arg); > > + rtx op = expand_promote_outgoing_argument (arg); > > machine_mode mode = insn_p->operand[i + 1].mode; > > /* Need to fixup modeless constant before testing predicate. */ > > op = fixup_modeless_constant (op, mode); > > @@ -12400,10 +12400,10 @@ ix86_expand_sse_comi_round (const struct > builtin_description *d, > > tree arg1 = CALL_EXPR_ARG (exp, 1); > > tree arg2 = CALL_EXPR_ARG (exp, 2); > > tree arg3 = CALL_EXPR_ARG (exp, 3); > > - rtx op0 = expand_normal (arg0); > > - rtx op1 = expand_normal (arg1); > > - rtx op2 = expand_normal (arg2); > > - rtx op3 = expand_normal (arg3); > > + rtx op0 = expand_promote_outgoing_argument (arg0); > > + rtx op1 = expand_promote_outgoing_argument (arg1); > > + rtx op2 = expand_promote_outgoing_argument (arg2); > > + rtx op3 = expand_promote_outgoing_argument (arg3); > > enum insn_code icode = d->icode; > > const struct insn_data_d *insn_p = &insn_data[icode]; > > machine_mode mode0 = insn_p->operand[0].mode; > > @@ -12870,7 +12870,7 @@ ix86_expand_round_builtin (const struct > builtin_description *d, > > for (i = 0; i < nargs; i++) > > { > > tree arg = CALL_EXPR_ARG (exp, i); > > - rtx op = expand_normal (arg); > > + rtx op = expand_promote_outgoing_argument (arg); > > machine_mode mode = insn_p->operand[i + 1].mode; > > bool match = insn_p->operand[i + 1].predicate (op, mode); > > > > @@ -13318,7 +13318,7 @@ ix86_expand_special_args_builtin (const struct > builtin_description *d, > > if (klass == store) > > { > > arg = CALL_EXPR_ARG (exp, 0); > > - op = expand_normal (arg); > > + op = expand_promote_outgoing_argument (arg); > > gcc_assert (target == 0); > > if (memory) > > { > > @@ -13355,7 +13355,7 @@ ix86_expand_special_args_builtin (const struct > builtin_description *d, > > machine_mode mode = insn_p->operand[i + 1].mode; > > > > arg = CALL_EXPR_ARG (exp, i + arg_adjust); > > - op = expand_normal (arg); > > + op = expand_promote_outgoing_argument (arg); > > > > if (i == memory) > > { > > @@ -13479,7 +13479,7 @@ ix86_expand_vec_init_builtin (tree type, tree > exp, rtx target) > > > > for (i = 0; i < n_elt; ++i) > > { > > - rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); > > + rtx x = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, i)); > > RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); > > } > > > > @@ -13505,7 +13505,7 @@ ix86_expand_vec_ext_builtin (tree exp, rtx > target) > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > elt = get_element_number (TREE_TYPE (arg0), arg1); > > > > tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); > > @@ -13727,9 +13727,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg1 = CALL_EXPR_ARG (exp, 0); > > arg2 = CALL_EXPR_ARG (exp, 1); > > arg0 = CALL_EXPR_ARG (exp, 2); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > mode0 = insn_data[icode].operand[0].mode; > > mode1 = insn_data[icode].operand[1].mode; > > mode2 = insn_data[icode].operand[2].mode; > > @@ -13750,7 +13750,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > return 0; > > > > case IX86_BUILTIN_LDMXCSR: > > - op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); > > + op0 = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, 0)); > > target = assign_stack_temp (SImode, GET_MODE_SIZE (SImode)); > > emit_move_insn (target, op0); > > emit_insn (gen_sse_ldmxcsr (target)); > > @@ -13763,7 +13763,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_CLFLUSH: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > icode = CODE_FOR_sse2_clflush; > > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > @@ -13773,7 +13773,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_CLWB: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > icode = CODE_FOR_clwb; > > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > @@ -13783,7 +13783,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_CLFLUSHOPT: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > icode = CODE_FOR_clflushopt; > > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > @@ -13796,9 +13796,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > arg2 = CALL_EXPR_ARG (exp, 2); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > if (!REG_P (op0)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > if (!REG_P (op1)) > > @@ -13814,8 +13814,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_MWAIT: > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > if (!REG_P (op1)) > > @@ -13827,9 +13827,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > arg2 = CALL_EXPR_ARG (exp, 2); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > if (!REG_P (op1)) > > @@ -13841,7 +13841,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_UMONITOR: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > op0 = ix86_zero_extend_to_Pmode (op0); > > emit_insn (gen_umonitor (Pmode, op0)); > > @@ -13851,8 +13851,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_TPAUSE: > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > @@ -13925,7 +13925,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_CLZERO: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > if (!REG_P (op0)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > emit_insn (gen_clzero (Pmode, op0)); > > @@ -13933,7 +13933,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_CLDEMOTE: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > icode = CODE_FOR_cldemote; > > if (!insn_data[icode].operand[0].predicate (op0, Pmode)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > @@ -13948,10 +13948,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg2 = CALL_EXPR_ARG (exp, 2); > > arg3 = CALL_EXPR_ARG (exp, 3); > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (V2DImode, op0); > > @@ -13988,9 +13988,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg1 = CALL_EXPR_ARG (exp, 1); // __m128i idata > > arg2 = CALL_EXPR_ARG (exp, 2); // const void *p > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > > > if (!address_operand (op0, V2DImode)) > > { > > @@ -14060,9 +14060,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg1 = CALL_EXPR_ARG (exp, 1); // const __m128i * idata > > arg2 = CALL_EXPR_ARG (exp, 2); // const void *p > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > > > if (!address_operand (op2, VOIDmode)) > > { > > @@ -14116,9 +14116,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg1 = CALL_EXPR_ARG (exp, 1); // __m128i key > > arg2 = CALL_EXPR_ARG (exp, 2); // void *h > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > @@ -14152,10 +14152,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg2 = CALL_EXPR_ARG (exp, 2); // __m128i keyhi > > arg3 = CALL_EXPR_ARG (exp, 3); // void *h > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > @@ -14191,10 +14191,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg2 = CALL_EXPR_ARG (exp, 2); // const int > > arg3 = CALL_EXPR_ARG (exp, 3); // const int > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > > > if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P > (op3)) > > { > > @@ -14264,8 +14264,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); // const void * > > arg1 = CALL_EXPR_ARG (exp, 1); // const int > > > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > if (!CONST_INT_P (op1)) > > { > > @@ -14295,7 +14295,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_UWRMSR: > > { > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > if (CONST_INT_P (op0)) > > { > > @@ -14309,7 +14309,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > if (fcode == IX86_BUILTIN_UWRMSR) > > { > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op1 = expand_normal (arg1); > > + op1 = expand_promote_outgoing_argument (arg1); > > op1 = force_reg (DImode, op1); > > icode = CODE_FOR_uwrmsr; > > target = 0; > > @@ -14384,10 +14384,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg1 = CALL_EXPR_ARG (exp, 1); > > arg2 = CALL_EXPR_ARG (exp, 2); > > arg3 = CALL_EXPR_ARG (exp, 3); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > > > if (!address_operand (op0, VOIDmode)) > > { > > @@ -14458,7 +14458,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > if (fcode == IX86_BUILTIN_RDPMC) > > { > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op2 = expand_normal (arg0); > > + op2 = expand_promote_outgoing_argument (arg0); > > if (!register_operand (op2, SImode)) > > op2 = copy_to_mode_reg (SImode, op2); > > > > @@ -14470,7 +14470,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > else if (fcode == IX86_BUILTIN_XGETBV) > > { > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op2 = expand_normal (arg0); > > + op2 = expand_promote_outgoing_argument (arg0); > > if (!register_operand (op2, SImode)) > > op2 = copy_to_mode_reg (SImode, op2); > > > > @@ -14496,7 +14496,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > emit_insn (insn); > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op4 = expand_normal (arg0); > > + op4 = expand_promote_outgoing_argument (arg0); > > if (!address_operand (op4, VOIDmode)) > > { > > op4 = convert_memory_address (Pmode, op4); > > @@ -14526,8 +14526,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > op0 = ix86_zero_extend_to_Pmode (op0); > > if (!address_operand (op1, VOIDmode)) > > @@ -14597,7 +14597,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > } > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > if (!address_operand (op0, VOIDmode)) > > { > > @@ -14614,8 +14614,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_XSETBV: > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > if (!REG_P (op0)) > > op0 = copy_to_mode_reg (SImode, op0); > > @@ -14657,8 +14657,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_XSAVEC64: > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > if (!address_operand (op0, VOIDmode)) > > { > > @@ -14754,7 +14754,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > case IX86_BUILTIN_LDTILECFG: > > case IX86_BUILTIN_STTILECFG: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > if (!address_operand (op0, VOIDmode)) > > { > > @@ -14772,7 +14772,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > case IX86_BUILTIN_LLWPCB: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > if (!register_operand (op0, Pmode)) > > op0 = ix86_zero_extend_to_Pmode (op0); > > @@ -14803,9 +14803,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > arg2 = CALL_EXPR_ARG (exp, 2); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > mode0 = insn_data[icode].operand[0].mode; > > > > if (!insn_data[icode].operand[0].predicate (op0, mode0)) > > @@ -14843,8 +14843,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > if (!CONST_INT_P (op1)) > > { > > @@ -14898,7 +14898,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx > subtarget, > > > > rdrand_step: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op1 = expand_normal (arg0); > > + op1 = expand_promote_outgoing_argument (arg0); > > if (!address_operand (op1, VOIDmode)) > > { > > op1 = convert_memory_address (Pmode, op1); > > @@ -14958,7 +14958,7 @@ rdrand_step: > > > > rdseed_step: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op1 = expand_normal (arg0); > > + op1 = expand_promote_outgoing_argument (arg0); > > if (!address_operand (op1, VOIDmode)) > > { > > op1 = convert_memory_address (Pmode, op1); > > @@ -15020,17 +15020,17 @@ rdseed_step: > > arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2. */ > > arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */ > > > > - op1 = expand_normal (arg0); > > + op1 = expand_promote_outgoing_argument (arg0); > > > > - op2 = expand_normal (arg1); > > + op2 = expand_promote_outgoing_argument (arg1); > > if (!register_operand (op2, mode0)) > > op2 = copy_to_mode_reg (mode0, op2); > > > > - op3 = expand_normal (arg2); > > + op3 = expand_promote_outgoing_argument (arg2); > > if (!register_operand (op3, mode0)) > > op3 = copy_to_mode_reg (mode0, op3); > > > > - op4 = expand_normal (arg3); > > + op4 = expand_promote_outgoing_argument (arg3); > > if (!address_operand (op4, VOIDmode)) > > { > > op4 = convert_memory_address (Pmode, op4); > > @@ -15087,7 +15087,7 @@ rdseed_step: > > case IX86_BUILTIN_WRITE_FLAGS: > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > if (!general_no_elim_operand (op0, word_mode)) > > op0 = copy_to_mode_reg (word_mode, op0); > > > > @@ -15177,8 +15177,8 @@ rdseed_step: > > kortest: > > arg0 = CALL_EXPR_ARG (exp, 0); /* Mask reg src1. */ > > arg1 = CALL_EXPR_ARG (exp, 1); /* Mask reg src2. */ > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > mode0 = insn_data[icode].operand[0].mode; > > mode1 = insn_data[icode].operand[1].mode; > > @@ -15482,11 +15482,11 @@ rdseed_step: > > arg2 = CALL_EXPR_ARG (exp, 2); > > arg3 = CALL_EXPR_ARG (exp, 3); > > arg4 = CALL_EXPR_ARG (exp, 4); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > - op4 = expand_normal (arg4); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > + op4 = expand_promote_outgoing_argument (arg4); > > /* Note the arg order is different from the operand order. */ > > mode0 = insn_data[icode].operand[1].mode; > > mode2 = insn_data[icode].operand[3].mode; > > @@ -15699,11 +15699,11 @@ rdseed_step: > > arg2 = CALL_EXPR_ARG (exp, 2); > > arg3 = CALL_EXPR_ARG (exp, 3); > > arg4 = CALL_EXPR_ARG (exp, 4); > > - op0 = expand_normal (arg0); > > - op1 = expand_normal (arg1); > > - op2 = expand_normal (arg2); > > - op3 = expand_normal (arg3); > > - op4 = expand_normal (arg4); > > + op0 = expand_promote_outgoing_argument (arg0); > > + op1 = expand_promote_outgoing_argument (arg1); > > + op2 = expand_promote_outgoing_argument (arg2); > > + op3 = expand_promote_outgoing_argument (arg3); > > + op4 = expand_promote_outgoing_argument (arg4); > > mode1 = insn_data[icode].operand[1].mode; > > mode2 = insn_data[icode].operand[2].mode; > > mode3 = insn_data[icode].operand[3].mode; > > @@ -15812,7 +15812,7 @@ rdseed_step: > > case IX86_BUILTIN_XABORT: > > icode = CODE_FOR_xabort; > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > mode0 = insn_data[icode].operand[0].mode; > > if (!insn_data[icode].operand[0].predicate (op0, mode0)) > > { > > @@ -15841,7 +15841,7 @@ rdseed_step: > > mode = (fcode == IX86_BUILTIN_INCSSPD ? SImode : DImode); > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > > > op0 = force_reg (mode, op0); > > > > @@ -15851,7 +15851,7 @@ rdseed_step: > > case IX86_BUILTIN_HRESET: > > icode = CODE_FOR_hreset; > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > op0 = force_reg (SImode, op0); > > emit_insn (gen_hreset (op0)); > > return 0; > > @@ -15859,7 +15859,7 @@ rdseed_step: > > case IX86_BUILTIN_RSTORSSP: > > case IX86_BUILTIN_CLRSSBSY: > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > icode = (fcode == IX86_BUILTIN_RSTORSSP > > ? CODE_FOR_rstorssp > > : CODE_FOR_clrssbsy); > > @@ -15881,9 +15881,9 @@ rdseed_step: > > ? SImode : DImode); > > > > arg0 = CALL_EXPR_ARG (exp, 0); > > - op0 = expand_normal (arg0); > > + op0 = expand_promote_outgoing_argument (arg0); > > arg1 = CALL_EXPR_ARG (exp, 1); > > - op1 = expand_normal (arg1); > > + op1 = expand_promote_outgoing_argument (arg1); > > > > op0 = force_reg (mode, op0); > > > > diff --git a/gcc/expr.cc b/gcc/expr.cc > > index caa1a72ba0b..0a1a70dab3c 100644 > > --- a/gcc/expr.cc > > +++ b/gcc/expr.cc > > @@ -14136,3 +14136,21 @@ int_expr_size (const_tree exp) > > > > return tree_to_shwi (size); > > } > > + > > +/* Expand an outgoing argument ARG with promotion. Since the C/C++ > > + frontends no longer promote integer argument smaller than int, > > + promote it when expanding built functions. */ > > + > > +rtx > > +expand_promote_outgoing_argument (tree arg) > > +{ > > + tree type = TREE_TYPE (arg); > > + if (INTEGRAL_TYPE_P (type) > > + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) > > + { > > + tree promoted_type = (TYPE_UNSIGNED (type) > > + ? unsigned_type_node : integer_type_node); > > + arg = fold_convert (promoted_type, arg); > > + } > > + return expand_normal (arg); > > +} > > diff --git a/gcc/expr.h b/gcc/expr.h > > index 04782b15f19..ed14750614b 100644 > > --- a/gcc/expr.h > > +++ b/gcc/expr.h > > @@ -312,6 +312,7 @@ extern rtx expand_expr_real_2 (const_sepops, rtx, > machine_mode, > > extern rtx expand_expr_real_gassign (gassign *, rtx, machine_mode, > > enum expand_modifier modifier, > > rtx * = nullptr, bool = false); > > +extern rtx expand_promote_outgoing_argument (tree); > > > > /* Generate code for computing expression EXP. > > An rtx for the computed value is returned. The value is never null. > > -- > > 2.47.0 > > >
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 5c4a8e07d62..ce887d96f6a 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -10415,8 +10415,8 @@ ix86_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); machine_mode tmode = insn_data[icode].operand[0].mode; machine_mode mode0 = insn_data[icode].operand[1].mode; machine_mode mode1 = insn_data[icode].operand[2].mode; @@ -10564,7 +10564,7 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target, for (i = 0; i < nargs; i++) { tree arg = CALL_EXPR_ARG (exp, i); - rtx op = expand_normal (arg); + rtx op = expand_promote_outgoing_argument (arg); int adjust = (comparison_p) ? 1 : 0; machine_mode mode = insn_data[icode].operand[i+adjust+1].mode; @@ -10691,7 +10691,7 @@ ix86_expand_unop_vec_merge_builtin (enum insn_code icode, tree exp, { rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); - rtx op1, op0 = expand_normal (arg0); + rtx op1, op0 = expand_promote_outgoing_argument (arg0); machine_mode tmode = insn_data[icode].operand[0].mode; machine_mode mode0 = insn_data[icode].operand[1].mode; @@ -10727,8 +10727,8 @@ ix86_expand_sse_compare (const struct builtin_description *d, rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); rtx op2; machine_mode tmode = insn_data[d->icode].operand[0].mode; machine_mode mode0 = insn_data[d->icode].operand[1].mode; @@ -10823,8 +10823,8 @@ ix86_expand_sse_comi (const struct builtin_description *d, tree exp, rtx pat, set_dst; tree arg0 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); enum insn_code icode = d->icode; const struct insn_data_d *insn_p = &insn_data[icode]; machine_mode mode0 = insn_p->operand[0].mode; @@ -10916,7 +10916,7 @@ ix86_expand_sse_round (const struct builtin_description *d, tree exp, { rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); - rtx op1, op0 = expand_normal (arg0); + rtx op1, op0 = expand_promote_outgoing_argument (arg0); machine_mode tmode = insn_data[d->icode].operand[0].mode; machine_mode mode0 = insn_data[d->icode].operand[1].mode; @@ -10948,8 +10948,8 @@ ix86_expand_sse_round_vec_pack_sfix (const struct builtin_description *d, rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); rtx op2; machine_mode tmode = insn_data[d->icode].operand[0].mode; machine_mode mode0 = insn_data[d->icode].operand[1].mode; @@ -10988,8 +10988,8 @@ ix86_expand_sse_ptest (const struct builtin_description *d, tree exp, rtx pat; tree arg0 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); machine_mode mode0 = insn_data[d->icode].operand[0].mode; machine_mode mode1 = insn_data[d->icode].operand[1].mode; enum rtx_code comparison = d->comparison; @@ -11047,11 +11047,11 @@ ix86_expand_sse_pcmpestr (const struct builtin_description *d, tree arg3 = CALL_EXPR_ARG (exp, 3); tree arg4 = CALL_EXPR_ARG (exp, 4); rtx scratch0, scratch1; - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - rtx op3 = expand_normal (arg3); - rtx op4 = expand_normal (arg4); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); + rtx op2 = expand_promote_outgoing_argument (arg2); + rtx op3 = expand_promote_outgoing_argument (arg3); + rtx op4 = expand_promote_outgoing_argument (arg4); machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm; tmode0 = insn_data[d->icode].operand[0].mode; @@ -11150,9 +11150,9 @@ ix86_expand_sse_pcmpistr (const struct builtin_description *d, tree arg1 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 2); rtx scratch0, scratch1; - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); + rtx op2 = expand_promote_outgoing_argument (arg2); machine_mode tmode0, tmode1, modev2, modev3, modeimm; tmode0 = insn_data[d->icode].operand[0].mode; @@ -12135,7 +12135,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, for (i = 0; i < nargs; i++) { tree arg = CALL_EXPR_ARG (exp, i); - rtx op = expand_normal (arg); + rtx op = expand_promote_outgoing_argument (arg); machine_mode mode = insn_p->operand[i + 1].mode; /* Need to fixup modeless constant before testing predicate. */ op = fixup_modeless_constant (op, mode); @@ -12400,10 +12400,10 @@ ix86_expand_sse_comi_round (const struct builtin_description *d, tree arg1 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 2); tree arg3 = CALL_EXPR_ARG (exp, 3); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - rtx op3 = expand_normal (arg3); + rtx op0 = expand_promote_outgoing_argument (arg0); + rtx op1 = expand_promote_outgoing_argument (arg1); + rtx op2 = expand_promote_outgoing_argument (arg2); + rtx op3 = expand_promote_outgoing_argument (arg3); enum insn_code icode = d->icode; const struct insn_data_d *insn_p = &insn_data[icode]; machine_mode mode0 = insn_p->operand[0].mode; @@ -12870,7 +12870,7 @@ ix86_expand_round_builtin (const struct builtin_description *d, for (i = 0; i < nargs; i++) { tree arg = CALL_EXPR_ARG (exp, i); - rtx op = expand_normal (arg); + rtx op = expand_promote_outgoing_argument (arg); machine_mode mode = insn_p->operand[i + 1].mode; bool match = insn_p->operand[i + 1].predicate (op, mode); @@ -13318,7 +13318,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, if (klass == store) { arg = CALL_EXPR_ARG (exp, 0); - op = expand_normal (arg); + op = expand_promote_outgoing_argument (arg); gcc_assert (target == 0); if (memory) { @@ -13355,7 +13355,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, machine_mode mode = insn_p->operand[i + 1].mode; arg = CALL_EXPR_ARG (exp, i + arg_adjust); - op = expand_normal (arg); + op = expand_promote_outgoing_argument (arg); if (i == memory) { @@ -13479,7 +13479,7 @@ ix86_expand_vec_init_builtin (tree type, tree exp, rtx target) for (i = 0; i < n_elt; ++i) { - rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); + rtx x = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, i)); RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); } @@ -13505,7 +13505,7 @@ ix86_expand_vec_ext_builtin (tree exp, rtx target) arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); elt = get_element_number (TREE_TYPE (arg0), arg1); tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); @@ -13727,9 +13727,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg1 = CALL_EXPR_ARG (exp, 0); arg2 = CALL_EXPR_ARG (exp, 1); arg0 = CALL_EXPR_ARG (exp, 2); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); mode0 = insn_data[icode].operand[0].mode; mode1 = insn_data[icode].operand[1].mode; mode2 = insn_data[icode].operand[2].mode; @@ -13750,7 +13750,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return 0; case IX86_BUILTIN_LDMXCSR: - op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); + op0 = expand_promote_outgoing_argument (CALL_EXPR_ARG (exp, 0)); target = assign_stack_temp (SImode, GET_MODE_SIZE (SImode)); emit_move_insn (target, op0); emit_insn (gen_sse_ldmxcsr (target)); @@ -13763,7 +13763,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_CLFLUSH: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); icode = CODE_FOR_sse2_clflush; if (!insn_data[icode].operand[0].predicate (op0, Pmode)) op0 = ix86_zero_extend_to_Pmode (op0); @@ -13773,7 +13773,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_CLWB: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); icode = CODE_FOR_clwb; if (!insn_data[icode].operand[0].predicate (op0, Pmode)) op0 = ix86_zero_extend_to_Pmode (op0); @@ -13783,7 +13783,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_CLFLUSHOPT: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); icode = CODE_FOR_clflushopt; if (!insn_data[icode].operand[0].predicate (op0, Pmode)) op0 = ix86_zero_extend_to_Pmode (op0); @@ -13796,9 +13796,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); if (!REG_P (op0)) op0 = ix86_zero_extend_to_Pmode (op0); if (!REG_P (op1)) @@ -13814,8 +13814,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_MWAIT: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); if (!REG_P (op1)) @@ -13827,9 +13827,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); if (!REG_P (op1)) @@ -13841,7 +13841,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_UMONITOR: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); op0 = ix86_zero_extend_to_Pmode (op0); emit_insn (gen_umonitor (Pmode, op0)); @@ -13851,8 +13851,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_TPAUSE: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); @@ -13925,7 +13925,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_CLZERO: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (!REG_P (op0)) op0 = ix86_zero_extend_to_Pmode (op0); emit_insn (gen_clzero (Pmode, op0)); @@ -13933,7 +13933,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_CLDEMOTE: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); icode = CODE_FOR_cldemote; if (!insn_data[icode].operand[0].predicate (op0, Pmode)) op0 = ix86_zero_extend_to_Pmode (op0); @@ -13948,10 +13948,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg2 = CALL_EXPR_ARG (exp, 2); arg3 = CALL_EXPR_ARG (exp, 3); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); if (!REG_P (op0)) op0 = copy_to_mode_reg (V2DImode, op0); @@ -13988,9 +13988,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg1 = CALL_EXPR_ARG (exp, 1); // __m128i idata arg2 = CALL_EXPR_ARG (exp, 2); // const void *p - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); if (!address_operand (op0, V2DImode)) { @@ -14060,9 +14060,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg1 = CALL_EXPR_ARG (exp, 1); // const __m128i * idata arg2 = CALL_EXPR_ARG (exp, 2); // const void *p - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); if (!address_operand (op2, VOIDmode)) { @@ -14116,9 +14116,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg1 = CALL_EXPR_ARG (exp, 1); // __m128i key arg2 = CALL_EXPR_ARG (exp, 2); // void *h - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); @@ -14152,10 +14152,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg2 = CALL_EXPR_ARG (exp, 2); // __m128i keyhi arg3 = CALL_EXPR_ARG (exp, 3); // void *h - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); @@ -14191,10 +14191,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg2 = CALL_EXPR_ARG (exp, 2); // const int arg3 = CALL_EXPR_ARG (exp, 3); // const int - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P (op3)) { @@ -14264,8 +14264,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); // const void * arg1 = CALL_EXPR_ARG (exp, 1); // const int - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!CONST_INT_P (op1)) { @@ -14295,7 +14295,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_UWRMSR: { arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (CONST_INT_P (op0)) { @@ -14309,7 +14309,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, if (fcode == IX86_BUILTIN_UWRMSR) { arg1 = CALL_EXPR_ARG (exp, 1); - op1 = expand_normal (arg1); + op1 = expand_promote_outgoing_argument (arg1); op1 = force_reg (DImode, op1); icode = CODE_FOR_uwrmsr; target = 0; @@ -14384,10 +14384,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); arg3 = CALL_EXPR_ARG (exp, 3); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); if (!address_operand (op0, VOIDmode)) { @@ -14458,7 +14458,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, if (fcode == IX86_BUILTIN_RDPMC) { arg0 = CALL_EXPR_ARG (exp, 0); - op2 = expand_normal (arg0); + op2 = expand_promote_outgoing_argument (arg0); if (!register_operand (op2, SImode)) op2 = copy_to_mode_reg (SImode, op2); @@ -14470,7 +14470,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, else if (fcode == IX86_BUILTIN_XGETBV) { arg0 = CALL_EXPR_ARG (exp, 0); - op2 = expand_normal (arg0); + op2 = expand_promote_outgoing_argument (arg0); if (!register_operand (op2, SImode)) op2 = copy_to_mode_reg (SImode, op2); @@ -14496,7 +14496,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, emit_insn (insn); arg0 = CALL_EXPR_ARG (exp, 0); - op4 = expand_normal (arg0); + op4 = expand_promote_outgoing_argument (arg0); if (!address_operand (op4, VOIDmode)) { op4 = convert_memory_address (Pmode, op4); @@ -14526,8 +14526,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); op0 = ix86_zero_extend_to_Pmode (op0); if (!address_operand (op1, VOIDmode)) @@ -14597,7 +14597,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, } arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (!address_operand (op0, VOIDmode)) { @@ -14614,8 +14614,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_XSETBV: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); @@ -14657,8 +14657,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_XSAVEC64: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!address_operand (op0, VOIDmode)) { @@ -14754,7 +14754,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_LDTILECFG: case IX86_BUILTIN_STTILECFG: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (!address_operand (op0, VOIDmode)) { @@ -14772,7 +14772,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_LLWPCB: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (!register_operand (op0, Pmode)) op0 = ix86_zero_extend_to_Pmode (op0); @@ -14803,9 +14803,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); mode0 = insn_data[icode].operand[0].mode; if (!insn_data[icode].operand[0].predicate (op0, mode0)) @@ -14843,8 +14843,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); if (!CONST_INT_P (op1)) { @@ -14898,7 +14898,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, rdrand_step: arg0 = CALL_EXPR_ARG (exp, 0); - op1 = expand_normal (arg0); + op1 = expand_promote_outgoing_argument (arg0); if (!address_operand (op1, VOIDmode)) { op1 = convert_memory_address (Pmode, op1); @@ -14958,7 +14958,7 @@ rdrand_step: rdseed_step: arg0 = CALL_EXPR_ARG (exp, 0); - op1 = expand_normal (arg0); + op1 = expand_promote_outgoing_argument (arg0); if (!address_operand (op1, VOIDmode)) { op1 = convert_memory_address (Pmode, op1); @@ -15020,17 +15020,17 @@ rdseed_step: arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2. */ arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */ - op1 = expand_normal (arg0); + op1 = expand_promote_outgoing_argument (arg0); - op2 = expand_normal (arg1); + op2 = expand_promote_outgoing_argument (arg1); if (!register_operand (op2, mode0)) op2 = copy_to_mode_reg (mode0, op2); - op3 = expand_normal (arg2); + op3 = expand_promote_outgoing_argument (arg2); if (!register_operand (op3, mode0)) op3 = copy_to_mode_reg (mode0, op3); - op4 = expand_normal (arg3); + op4 = expand_promote_outgoing_argument (arg3); if (!address_operand (op4, VOIDmode)) { op4 = convert_memory_address (Pmode, op4); @@ -15087,7 +15087,7 @@ rdseed_step: case IX86_BUILTIN_WRITE_FLAGS: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); if (!general_no_elim_operand (op0, word_mode)) op0 = copy_to_mode_reg (word_mode, op0); @@ -15177,8 +15177,8 @@ rdseed_step: kortest: arg0 = CALL_EXPR_ARG (exp, 0); /* Mask reg src1. */ arg1 = CALL_EXPR_ARG (exp, 1); /* Mask reg src2. */ - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); mode0 = insn_data[icode].operand[0].mode; mode1 = insn_data[icode].operand[1].mode; @@ -15482,11 +15482,11 @@ rdseed_step: arg2 = CALL_EXPR_ARG (exp, 2); arg3 = CALL_EXPR_ARG (exp, 3); arg4 = CALL_EXPR_ARG (exp, 4); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); - op4 = expand_normal (arg4); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); + op4 = expand_promote_outgoing_argument (arg4); /* Note the arg order is different from the operand order. */ mode0 = insn_data[icode].operand[1].mode; mode2 = insn_data[icode].operand[3].mode; @@ -15699,11 +15699,11 @@ rdseed_step: arg2 = CALL_EXPR_ARG (exp, 2); arg3 = CALL_EXPR_ARG (exp, 3); arg4 = CALL_EXPR_ARG (exp, 4); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - op3 = expand_normal (arg3); - op4 = expand_normal (arg4); + op0 = expand_promote_outgoing_argument (arg0); + op1 = expand_promote_outgoing_argument (arg1); + op2 = expand_promote_outgoing_argument (arg2); + op3 = expand_promote_outgoing_argument (arg3); + op4 = expand_promote_outgoing_argument (arg4); mode1 = insn_data[icode].operand[1].mode; mode2 = insn_data[icode].operand[2].mode; mode3 = insn_data[icode].operand[3].mode; @@ -15812,7 +15812,7 @@ rdseed_step: case IX86_BUILTIN_XABORT: icode = CODE_FOR_xabort; arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); mode0 = insn_data[icode].operand[0].mode; if (!insn_data[icode].operand[0].predicate (op0, mode0)) { @@ -15841,7 +15841,7 @@ rdseed_step: mode = (fcode == IX86_BUILTIN_INCSSPD ? SImode : DImode); arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); op0 = force_reg (mode, op0); @@ -15851,7 +15851,7 @@ rdseed_step: case IX86_BUILTIN_HRESET: icode = CODE_FOR_hreset; arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); op0 = force_reg (SImode, op0); emit_insn (gen_hreset (op0)); return 0; @@ -15859,7 +15859,7 @@ rdseed_step: case IX86_BUILTIN_RSTORSSP: case IX86_BUILTIN_CLRSSBSY: arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); icode = (fcode == IX86_BUILTIN_RSTORSSP ? CODE_FOR_rstorssp : CODE_FOR_clrssbsy); @@ -15881,9 +15881,9 @@ rdseed_step: ? SImode : DImode); arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); + op0 = expand_promote_outgoing_argument (arg0); arg1 = CALL_EXPR_ARG (exp, 1); - op1 = expand_normal (arg1); + op1 = expand_promote_outgoing_argument (arg1); op0 = force_reg (mode, op0); diff --git a/gcc/expr.cc b/gcc/expr.cc index caa1a72ba0b..0a1a70dab3c 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -14136,3 +14136,21 @@ int_expr_size (const_tree exp) return tree_to_shwi (size); } + +/* Expand an outgoing argument ARG with promotion. Since the C/C++ + frontends no longer promote integer argument smaller than int, + promote it when expanding built functions. */ + +rtx +expand_promote_outgoing_argument (tree arg) +{ + tree type = TREE_TYPE (arg); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + { + tree promoted_type = (TYPE_UNSIGNED (type) + ? unsigned_type_node : integer_type_node); + arg = fold_convert (promoted_type, arg); + } + return expand_normal (arg); +} diff --git a/gcc/expr.h b/gcc/expr.h index 04782b15f19..ed14750614b 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -312,6 +312,7 @@ extern rtx expand_expr_real_2 (const_sepops, rtx, machine_mode, extern rtx expand_expr_real_gassign (gassign *, rtx, machine_mode, enum expand_modifier modifier, rtx * = nullptr, bool = false); +extern rtx expand_promote_outgoing_argument (tree); /* Generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null.
Since the C/C++/Ada frontends no longer promote integer argument smaller than int, add expand_promote_outgoing_argument to promote it when expanding builtin functions. PR middle-end/14907 * expr.cc (expand_promote_outgoing_argument): New function. * expr.h (expand_promote_outgoing_argument): New prototype. * config/i386/i386-expand.cc (ix86_expand_binop_builtin): Call expand_promote_outgoing_argument to expand the outgoing argument. (ix86_expand_multi_arg_builtin): Likewise. (ix86_expand_unop_vec_merge_builtin): Likewise. (ix86_expand_sse_compare): Likewise. (ix86_expand_sse_comi): Likewise. (ix86_expand_sse_round): Likewise. (ix86_expand_sse_round_vec_pack_sfix): Likewise. (ix86_expand_sse_ptest): Likewise. (ix86_expand_sse_pcmpestr): Likewise. (ix86_expand_sse_pcmpistr): Likewise. (ix86_expand_args_builtin): Likewise. (ix86_expand_sse_comi_round): Likewise. (ix86_expand_round_builtin): Likewise. (ix86_expand_special_args_builtin): Likewise. (ix86_expand_vec_init_builtin): Likewise. (ix86_expand_vec_ext_builtin): Likewise. (ix86_expand_builtin): Likewise. Signed-off-by: H.J. Lu <hjl.tools@gmail.com> --- gcc/config/i386/i386-expand.cc | 244 ++++++++++++++++----------------- gcc/expr.cc | 18 +++ gcc/expr.h | 1 + 3 files changed, 141 insertions(+), 122 deletions(-)