On Wed, Nov 13, 2024 at 5:57 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > On Tue, Nov 12, 2024 at 9:30 PM Richard Biener > <richard.guent...@gmail.com> wrote: > > > > On Tue, Nov 12, 2024 at 1:49 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > When passing 0xff as an unsigned char function argument, the C frontend > > > promotion will promote it to int: > > > > > > <integer_cst 0x7fffe6aa23a8 type <integer_type 0x7fffe98225e8 int> > > > constant 255> > > > > > > and expand_normal always returns the rtx value using the sign-extended > > > representation, > > > > > > (const_int 255 [0xff]) > > > > > > If the C frontend doesn't promote unsigned char to int, expand_normal will > > > get > > > > > > <integer_cst 0x7fffe9824018 type <integer_type 0x7fffe9822348 unsigned > > > char > co > > > nstant 255> > > > > > > and return > > > > > > (const_int -1 [0xffffffffffffffff]) > > > > that looks wrong to me, but in other places we ensure > > to use trunc_int_for_mode (), not some odd function like > > you introduce here? > > I opened: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117547 >
Here is the v2 patch with reference to PR target/117547. When passing 0xff as an unsigned char function argument with the C frontend promotion, expand_normal gets <integer_cst 0x7fffe6aa23a8 type <integer_type 0x7fffe98225e8 int> constant 255> and returns the rtx value using the sign-extended representation: (const_int 255 [0xff]) Without the C frontend promotion, expand_normal gets <integer_cst 0x7fffe9824018 type <integer_type 0x7fffe9822348 unsigned char > co nstant 255> and returns (const_int -1 [0xffffffffffffffff]) which doesn't work with the IN_RANGE predicates. Extract the 8-bit/16-bit integer constants to always return (const_int 255 [0xff]) so that the return value can be used with the IN_RANGE predicates, like const_0_to_255_operand, without the C frontend promotion. PR target/117547 * config/i386/i386-expand.cc (ix86_expand_integer_cst_argument): New function. (ix86_expand_args_builtin): Call ix86_expand_integer_cst_argument to expand the argument before calling fixup_modeless_constant. (ix86_expand_round_builtin): Likewise. (ix86_expand_special_args_builtin): Likewise. (ix86_expand_builtin): Likewise. -- H.J.
From 7a2c3934629151d186f7a8f0f8f100d910069d7e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 12 Nov 2024 09:03:31 +0800 Subject: [PATCH v2] i386: Add ix86_expand_integer_cst_argument When passing 0xff as an unsigned char function argument with the C frontend promotion, expand_normal gets <integer_cst 0x7fffe6aa23a8 type <integer_type 0x7fffe98225e8 int> constant 255> and returns the rtx value using the sign-extended representation: (const_int 255 [0xff]) Without the C frontend promotion, expand_normal gets <integer_cst 0x7fffe9824018 type <integer_type 0x7fffe9822348 unsigned char > constant 255> and returns (const_int -1 [0xffffffffffffffff]) which doesn't work with the IN_RANGE predicates. Extract the 8-bit/16-bit integer constants to always return (const_int 255 [0xff]) so that the return value can be used with the IN_RANGE predicates, like const_0_to_255_operand, without the C frontend promotion. PR target/117547 * config/i386/i386-expand.cc (ix86_expand_integer_cst_argument): New function. (ix86_expand_args_builtin): Call ix86_expand_integer_cst_argument to expand the argument before calling fixup_modeless_constant. (ix86_expand_round_builtin): Likewise. (ix86_expand_special_args_builtin): Likewise. (ix86_expand_builtin): Likewise. Signed-off-by: H.J. Lu <hjl.to...@gmail.com> --- gcc/config/i386/i386-expand.cc | 55 ++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 5c4a8e07d62..2145bd0aaf5 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -11243,6 +11243,51 @@ fixup_modeless_constant (rtx x, machine_mode mode) return x; } +/* Expand the outgoing argument ARG and extract INTEGER_CST rtx value + suitable for the IN_RANGE predicates. */ + +static rtx +ix86_expand_integer_cst_argument (tree arg) +{ + /* When passing 0xff as an unsigned char function argument with the + C frontend promotion, expand_normal gets + + <integer_cst 0x7fffe6aa23a8 type <integer_type 0x7fffe98225e8 int> constant 255> + + and returns the rtx value using the sign-extended representation: + + (const_int 255 [0xff]) + + Without the C frontend promotion, expand_normal gets + + <integer_cst 0x7fffe9824018 type <integer_type 0x7fffe9822348 unsigned char > constant 255> + + and returns + + (const_int -1 [0xffffffffffffffff]) + + which doesn't work with the IN_RANGE predicates. Extract the + 8-bit/16-bit integer constants to always return + + (const_int 255 [0xff]) + + so that the return value can be used with the IN_RANGE predicates, + like const_0_to_255_operand, without the C frontend promotion. */ + + if (TREE_CODE (arg) == INTEGER_CST) + { + tree type = TREE_TYPE (arg); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + { + HOST_WIDE_INT cst = TREE_INT_CST_LOW (arg); + return GEN_INT (cst); + } + } + + return expand_normal (arg); +} + /* Subroutine of ix86_expand_builtin to take care of insns with variable number of operands. */ @@ -12135,7 +12180,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 = ix86_expand_integer_cst_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); @@ -12870,7 +12915,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 = ix86_expand_integer_cst_argument (arg); machine_mode mode = insn_p->operand[i + 1].mode; bool match = insn_p->operand[i + 1].predicate (op, mode); @@ -13355,7 +13400,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 = ix86_expand_integer_cst_argument (arg); if (i == memory) { @@ -15485,7 +15530,7 @@ rdseed_step: op0 = expand_normal (arg0); op1 = expand_normal (arg1); op2 = expand_normal (arg2); - op3 = expand_normal (arg3); + op3 = ix86_expand_integer_cst_argument (arg3); op4 = expand_normal (arg4); /* Note the arg order is different from the operand order. */ mode0 = insn_data[icode].operand[1].mode; @@ -15700,7 +15745,7 @@ rdseed_step: arg3 = CALL_EXPR_ARG (exp, 3); arg4 = CALL_EXPR_ARG (exp, 4); op0 = expand_normal (arg0); - op1 = expand_normal (arg1); + op1 = ix86_expand_integer_cst_argument (arg1); op2 = expand_normal (arg2); op3 = expand_normal (arg3); op4 = expand_normal (arg4); -- 2.47.0