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;
 }

Reply via email to