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 <[email protected]>
---
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