On Thu, Jun 26, 2014 at 07:41:22PM +1000, Kugan wrote: > 2014-06-26 Kugan Vivekanandarajah <kug...@linaro.org> > > * calls.c (precompute_arguments): Use new SUBREG_PROMOTED_SET > instead of SUBREG_PROMOTED_UNSIGNED_SET
Missing full stop. > --- a/gcc/cfgexpand.c > +++ b/gcc/cfgexpand.c > @@ -3297,7 +3297,7 @@ expand_gimple_stmt_1 (gimple stmt) > ; > else if (promoted) > { > - int unsignedp = SUBREG_PROMOTED_UNSIGNED_P (target); > + int unsignedp = SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED; >From what I understand, here you want the -1/0/1 value and not 2, so that is int unsignedp = SUBREG_PROMOTED_GET (target); if (unsignedp == SRP_SIGNED_AND_UNSIGNED) unsignedp = SRP_UNSIGNED; I think. Do you agree? BTW, the final patch will probably need to be tested on one of the weirdo ptr_extend targets (ia64-hpux or x86_64-linux -mx32). > --- a/gcc/expr.c > +++ b/gcc/expr.c > @@ -329,7 +329,7 @@ convert_move (rtx to, rtx from, int unsignedp) > if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from) > && (GET_MODE_PRECISION (GET_MODE (SUBREG_REG (from))) > >= GET_MODE_PRECISION (to_mode)) > - && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp) > + && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp)) I think unsignedp (misnamed) may be -1/0/1 here, so either SUBREG_CHECK_PROMOTED_SIGN needs to handle those 3, or you need to use something else. If it handles all 3 values, then it would be say ((SIGN) == SRP_POINTER ? SUBREG_PROMOTED_GET (RTX) == SRP_POINTER : (SIGN) == SRP_SIGNED ? SUBREG_PROMOTED_SIGNED_P (RTX) : SUBREG_PROMOTED_UNSIGNED_P (RTX)) or so. > from = gen_lowpart (to_mode, from), from_mode = to_mode; > > gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to)); > @@ -703,7 +703,7 @@ convert_modes (enum machine_mode mode, enum machine_mode > oldmode, rtx x, int uns > > if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x) > && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode) > - && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp) > + && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp)) > x = gen_lowpart (mode, SUBREG_REG (x)); Similarly. > @@ -5203,24 +5203,25 @@ store_expr (tree exp, rtx target, int call_param_p, > bool nontemporal) > == TYPE_PRECISION (TREE_TYPE (exp))) > { > if (TYPE_UNSIGNED (TREE_TYPE (exp)) > - != SUBREG_PROMOTED_UNSIGNED_P (target)) > + != SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED) Here TYPE_UNSIGNED is 0 or 1, so if you define SUBREG_PROMOTED_CHECK_SIGN the way suggested above, this would be SUBREG_PROMOTED_CHECK_SIGN then, or if (TYPE_UNSIGNED (TREE_TYPE (exp)) ? SUBREG_PROMOTED_UNSIGNED_P (target) : SUBREG_PROMOTED_SIGNED_P (target)) > { > /* Some types, e.g. Fortran's logical*4, won't have a signed > version, so use the mode instead. */ > tree ntype > = (signed_or_unsigned_type_for > - (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp))); > + (SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED, I'd just use TYPE_UNSIGNED (TREE_TYPE (exp)) here instead, no reason to repeat what the guarding condition did. > + TREE_TYPE (exp))); > if (ntype == NULL) > ntype = lang_hooks.types.type_for_mode > (TYPE_MODE (TREE_TYPE (exp)), > - SUBREG_PROMOTED_UNSIGNED_P (target)); > + SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED); > > exp = fold_convert_loc (loc, ntype, exp); > } > > exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode > (GET_MODE (SUBREG_REG (target)), > - SUBREG_PROMOTED_UNSIGNED_P (target)), > + SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED), > exp); I believe fold_convert only considers zero and non-zero, so no idea what we want here for SRP_POINTER. Doing what we used to do would be SUBREG_PROMOTED_GET (target) != SRP_SIGNED. > > inner_target = SUBREG_REG (target); > @@ -5234,14 +5235,14 @@ store_expr (tree exp, rtx target, int call_param_p, > bool nontemporal) > if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode) > { > temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)), > - temp, SUBREG_PROMOTED_UNSIGNED_P (target)); > + temp, SUBREG_PROMOTED_GET (target) & > SRP_UNSIGNED); > temp = convert_modes (GET_MODE (SUBREG_REG (target)), > GET_MODE (target), temp, > - SUBREG_PROMOTED_UNSIGNED_P (target)); > + SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED); > } > > convert_move (SUBREG_REG (target), temp, > - SUBREG_PROMOTED_UNSIGNED_P (target)); > + SUBREG_PROMOTED_GET (target) & SRP_UNSIGNED); In all 3 cases here you want -1/0/1 and treat SRP_SIGNED_AND_UNSIGNED as probably 1, so supposedly you want a macro for that and use it in the 3 cases here, in expand_gimple_stmt_1 etc. > --- a/gcc/rtl.h > +++ b/gcc/rtl.h > @@ -1585,29 +1585,67 @@ get_full_set_src_cost (rtx x, struct full_rtx_costs > *c) > #define SUBREG_PROMOTED_VAR_P(RTX) \ > (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED", (RTX), SUBREG)->in_struct) > > -#define SUBREG_PROMOTED_UNSIGNED_SET(RTX, VAL) > \ > -do { \ > - rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_SET", \ > - (RTX), SUBREG); \ > - if ((VAL) < 0) \ > - _rtx->volatil = 1; > \ > - else { \ > - _rtx->volatil = 0; > \ > - _rtx->unchanging = (VAL); > \ > - } \ > -} while (0) > - > /* Valid for subregs which are SUBREG_PROMOTED_VAR_P(). In that case > this gives the necessary extensions: > - 0 - signed > - 1 - normal unsigned > + 0 - signed (SPR_SIGNED) > + 1 - normal unsigned (SPR_UNSIGNED) > + 2 - value is both sign and unsign extended for mode > + (SPR_SIGNED_AND_UNSIGNED). > -1 - pointer unsigned, which most often can be handled like unsigned > extension, except for generating instructions where we need to > - emit special code (ptr_extend insns) on some architectures. */ > + emit special code (ptr_extend insns) on some architectures > + (SPR_POINTER). */ > + > +const unsigned int SRP_POINTER = -1; > +const unsigned int SRP_SIGNED = 0; > +const unsigned int SRP_UNSIGNED = 1; > +const unsigned int SRP_SIGNED_AND_UNSIGNED = 2; > + > +/* Sets promoted mode for SUBREG_PROMOTED_VAR_P(). */ > +#define SUBREG_PROMOTED_SET(RTX, VAL) > \ > +do { \ > + rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SET", \ > + (RTX), SUBREG); \ > + switch ((VAL)) \ Please avoid the extra ()s, switch (VAL) is enough. > +/* Checks if RTX of SUBREG_PROMOTED_VAR_P() is promotd for given SIGN. */ promoted, typo. > +#define SUBREG_CHECK_PROMOTED_SIGN(RTX, SIGN) \ > + ((SIGN) ? SUBREG_PROMOTED_GET ((RTX)) != SRP_SIGNED \ > + : SUBREG_PROMOTED_SIGNED_P ((RTX))) See above. And note the ((RTX)) should have been (RTX) anyway. > @@ -5587,7 +5587,8 @@ simplify_subreg (enum machine_mode outermode, rtx op, > { > newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset); > if (SUBREG_PROMOTED_VAR_P (op) > - && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0 > + && (SUBREG_PROMOTED_UNSIGNED_P (op) > + || (SUBREG_PROMOTED_SIGNED_P (op))) SUBREG_PROMOTED_GET (op) != SRP_POINTER ? Also note the extra ()s. > && GET_MODE_CLASS (outermode) == MODE_INT > && IN_RANGE (GET_MODE_SIZE (outermode), > GET_MODE_SIZE (innermode), > @@ -5595,8 +5596,7 @@ simplify_subreg (enum machine_mode outermode, rtx op, > && subreg_lowpart_p (newx)) > { > SUBREG_PROMOTED_VAR_P (newx) = 1; > - SUBREG_PROMOTED_UNSIGNED_SET > - (newx, SUBREG_PROMOTED_UNSIGNED_P (op)); > + SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op)); > } > return newx; > } Jakub