@@ -360,7 +360,7 @@ add_dependence (temp_expr_table_p tab, i
/* Return TRUE if expression STMT is suitable for replacement. */
static inline bool
-is_replaceable_p (gimple stmt)
+is_replaceable_p (gimple stmt, bool ter)
{
use_operand_p use_p;
tree def;
@@ -386,7 +386,7 @@ is_replaceable_p (gimple stmt)
return false;
/* If the use isn't in this block, it wont be replaced either. */
- if (gimple_bb (use_stmt) != gimple_bb (stmt))
+ if (ter && gimple_bb (use_stmt) != gimple_bb (stmt))
return false;
locus1 = gimple_location (stmt);
@@ -404,6 +404,7 @@ is_replaceable_p (gimple stmt)
}
if (!optimize
+ && ter
&& ((locus1 && locus1 != locus2) || (block1 && block1 != block2)))
return false;
@@ -416,7 +417,7 @@ is_replaceable_p (gimple stmt)
return false;
/* Without alias info we can't move around loads. */
- if (!optimize
+ if ((!optimize || !ter)
&& gimple_assign_single_p (stmt)
&& !is_gimple_val (gimple_assign_rhs1 (stmt)))
return false;
@@ -444,6 +445,16 @@ is_replaceable_p (gimple stmt)
}
+/* Variant of is_replaceable_p test for use in EXPAND_INITIALIZER
+ expansion. */
+
+bool
+stmt_is_replaceable_p (gimple stmt)
+{
+ return is_replaceable_p (stmt, false);
+}
+
+
/* This function will remove the expression for VERSION from replacement
consideration in table TAB. If FREE_EXPR is true, then remove the
expression from consideration as well by freeing the decl uid bitmap. */
@@ -477,7 +488,7 @@ process_replaceable (temp_expr_table_p t
ssa_op_iter iter;
bitmap def_vars, use_vars;
- gcc_checking_assert (is_replaceable_p (stmt));
+ gcc_checking_assert (is_replaceable_p (stmt, true));
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def);
@@ -589,7 +600,7 @@ find_replaceable_in_bb (temp_expr_table_
if (is_gimple_debug (stmt))
continue;
- stmt_replaceable = is_replaceable_p (stmt);
+ stmt_replaceable = is_replaceable_p (stmt, true);
/* Determine if this stmt finishes an existing expression. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
@@ -8387,6 +8387,12 @@ expand_expr_real_1 (tree exp, rtx target
NULL);
g = get_gimple_for_ssa_name (exp);
+ /* For EXPAND_INITIALIZER try harder to get something simpler. */
+ if (g == NULL
+ && modifier == EXPAND_INITIALIZER
+ && !SSA_NAME_IS_DEFAULT_DEF (exp)
+ && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
+ g = SSA_NAME_DEF_STMT (exp);
if (g)
return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode,
modifier, NULL);
@@ -852,6 +852,9 @@ bool fixup_noreturn_call (gimple stmt);
/* In ipa-pure-const.c */
void warn_function_noreturn (tree);
+/* In tree-ssa-ter.c */
+bool stmt_is_replaceable_p (gimple);
+
#include "tree-flow-inline.h"
void swap_tree_operands (gimple, tree *, tree *);
@@ -0,0 +1,22 @@
+/* PR inline-asm/23200 */
+/* { dg-do compile { target nonpic } } */
+/* { dg-options "-O0" } */
+
+static char var;
+
+void
+foo (void)
+{
+ asm volatile ("" :: "i" (&var + 1));
+}
+
+typedef int T[];
+typedef T *P;
+
+int var2;
+
+void
+bar (void)
+{
+ asm volatile ("" :: "i"(&(*(P)&var2)[1]));
+}
@@ -4,7 +4,7 @@
/* { dg-error "impossible constraint" "" { target *-*-* } 13 } */
/* { dg-error "impossible constraint" "" { target *-*-* } 14 } */
/* { dg-error "impossible constraint" "" { target *-*-* } 15 } */
-/* { dg-error "impossible constraint" "" { target *-*-* } 16 } */
+
int bar (int);
void
foo (int *x, int y)
@@ -13,6 +13,6 @@ foo (int *x, int y)
asm ("# %0" :: "i" (x)); /* { dg-warning "probably doesn't match" } */
asm ("# %0" :: "i" (bar (*x))); /* { dg-warning "probably doesn't match" } */
asm ("# %0" :: "i" (*x + 0x11)); /* { dg-warning "probably doesn't match" } */
- asm ("# %0" :: "i" (constant)); /* { dg-warning "probably doesn't match" } */
+ asm ("# %0" :: "i" (constant)); /* optimized */
asm ("# %0" :: "i" (y * 0)); /* folded */
}