This patch rewrites the condition: if (tmode != address_mode && tmode != pointer_mode) tmode = address_mode;
to the equivalent: tmode == pointer_mode ? pointer_mode : address_mode The latter has the advantage that the result is naturally a scalar_int_mode; a later mechanical patch makes it one. 2017-07-13 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * expr.c (expand_expr_addr_expr): Add a new_tmode local variable that is always either address_mode or pointer_mode. Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-07-13 09:18:48.752992795 +0100 +++ gcc/expr.c 2017-07-13 09:18:49.132963429 +0100 @@ -7902,20 +7902,21 @@ expand_expr_addr_expr (tree exp, rtx tar /* We can get called with some Weird Things if the user does silliness like "(short) &a". In that case, convert_memory_address won't do the right thing, so ignore the given target mode. */ - if (tmode != address_mode && tmode != pointer_mode) - tmode = address_mode; + machine_mode new_tmode = (tmode == pointer_mode + ? pointer_mode + : address_mode); result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target, - tmode, modifier, as); + new_tmode, modifier, as); /* Despite expand_expr claims concerning ignoring TMODE when not strictly convenient, stuff breaks if we don't honor it. Note that combined with the above, we only do this for pointer modes. */ rmode = GET_MODE (result); if (rmode == VOIDmode) - rmode = tmode; - if (rmode != tmode) - result = convert_memory_address_addr_space (tmode, result, as); + rmode = new_tmode; + if (rmode != new_tmode) + result = convert_memory_address_addr_space (new_tmode, result, as); return result; }