diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6614b548b2a7460f9c14204854948692ebd1095c..62a3fc7def66860281b4dac788232f4a0d05d7f3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-01-24  Richard Henderson  <rth@redehat.com>
+
+	* alias.h (ALIAS_SET_MEMORY_BARRIER): New.
+	* alias.c (true_dependence): Respect it.
+	(canon_true_dependence, write_dependence_p): Likewise.
+	* builtins.c (get_builtin_sync_mem): Set it.
+
 2006-01-25  Zdenek Dvorak <dvorakz@suse.cz>
 
 	* loop-iv.c (iv_analysis_loop_init): Use df analysis in a more
diff --git a/gcc/alias.c b/gcc/alias.c
index 4806019909272c11a253082d3948d01ac95ac00f..68dff253abf82e0a840d989b7f5938c8ae13d3f3 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1,5 +1,5 @@
 /* Alias analysis for GNU C
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by John Carr (jfc@mit.edu).
 
@@ -2209,6 +2209,9 @@ true_dependence (rtx mem, enum machine_mode mem_mode, rtx x,
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
@@ -2282,6 +2285,9 @@ canon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr,
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
@@ -2341,6 +2347,9 @@ write_dependence_p (rtx mem, rtx x, int writep)
     return 1;
   if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return 1;
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
 
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
diff --git a/gcc/alias.h b/gcc/alias.h
index c9154b3e58f85845397f6ed8e5c8eb2cc4323579..83cc2d55094f4344f3202888f7a6e1bccf788a04 100644
--- a/gcc/alias.h
+++ b/gcc/alias.h
@@ -27,4 +27,10 @@ extern HOST_WIDE_INT get_frame_alias_set (void);
 extern void record_base_value (unsigned int, rtx, int);
 extern bool component_uses_parent_alias_set (tree);
 
+/* This alias set can be used to force a memory to conflict with all
+   other memories, creating a barrier across which no memory reference
+   can move.  Note that there are other legacy ways to create such
+   memory barriers, including an address of SCRATCH.  */
+#define ALIAS_SET_MEMORY_BARRIER	((HOST_WIDE_INT) -1)
+
 #endif /* GCC_ALIAS_H */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 2d4322f97004d28d4d5f3743ae42778d61030a80..896fc48a4dedbc61415492b07d408e19bd16594c 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1,6 +1,6 @@
 /* Expand builtin functions.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -5406,6 +5406,7 @@ get_builtin_sync_mem (tree loc, enum machine_mode mode)
   mem = validize_mem (gen_rtx_MEM (mode, addr));
 
   set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
+  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
   MEM_VOLATILE_P (mem) = 1;
 
   return mem;