diff --git a/sysdeps/i386/i586/multiarch/bzero-i386.S b/sysdeps/i386/i586/multiarch/bzero-i386.S
new file mode 100644
index 0000000..02c0874
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero-i386.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/bzero.S>
diff --git a/sysdeps/i386/i586/multiarch/bzero-i586.S b/sysdeps/i386/i586/multiarch/bzero-i586.S
new file mode 100644
index 0000000..b33a36c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/bzero-i586.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/bzero.c b/sysdeps/i386/i586/multiarch/bzero.c
new file mode 100644
index 0000000..c14c064
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/bzero.c>
diff --git a/sysdeps/i386/i586/multiarch/memset-i386.S b/sysdeps/i386/i586/multiarch/memset-i386.S
new file mode 100644
index 0000000..3d2a287
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset-i386.S
@@ -0,0 +1,5 @@
+#define memset __memset_i386
+#define __memset_chk __memset_chk_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/memset.S>
diff --git a/sysdeps/i386/i586/multiarch/memset-i586.S b/sysdeps/i386/i586/multiarch/memset-i586.S
new file mode 100644
index 0000000..47b29ce
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memset-i586.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/memset.c b/sysdeps/i386/i586/multiarch/memset.c
new file mode 100644
index 0000000..57037dd
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memset.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 31bfd39..59072b9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,14 +1,8 @@
-ifeq ($(subdir),csu)
-tests += test-multiarch
-gen-as-const-headers += ifunc-defines.sym
-endif
-
 ifeq ($(subdir),string)
-gen-as-const-headers += locale-defines.sym
-sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
+sysdep_routines += memcpy-ssse3 mempcpy-ssse3 \
 		   memmove-ssse3 memcpy-ssse3-rep mempcpy-ssse3-rep \
 		   memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
-		   memset-sse2-rep bzero-sse2-rep strcmp-ssse3 \
+		   strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
 		   memcmp-ssse3 memcmp-sse4 varshift \
 		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
diff --git a/sysdeps/i386/i686/multiarch/bzero-i386.S b/sysdeps/i386/i686/multiarch/bzero-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/bzero-i586.S b/sysdeps/i386/i686/multiarch/bzero-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/bzero-i686.S b/sysdeps/i386/i686/multiarch/bzero-i686.S
new file mode 100644
index 0000000..1af300c
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/bzero-i686.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/bzero.S b/sysdeps/i386/i686/multiarch/bzero.S
deleted file mode 100644
index 95c96a8..0000000
--- a/sysdeps/i386/i686/multiarch/bzero.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of bzero
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__bzero)
-	.type	__bzero, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__bzero_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX ( __bzero_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bzero_sse2_rep)
-2:	ret
-END(__bzero)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __bzero_ia32, @function; \
-	.p2align 4; \
-	.globl __bzero_ia32; \
-	.hidden __bzero_ia32; \
-	__bzero_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __bzero_ia32, .-__bzero_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI___bzero; __GI___bzero = __bzero_ia32
-# endif
-#endif
-
-#include "../bzero.S"
diff --git a/sysdeps/i386/i686/multiarch/bzero.c b/sysdeps/i386/i686/multiarch/bzero.c
new file mode 100644
index 0000000..c14c064
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/bzero.c>
diff --git a/sysdeps/i386/i686/multiarch/memset-i386.S b/sysdeps/i386/i686/multiarch/memset-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memset-i586.S b/sysdeps/i386/i686/multiarch/memset-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memset-i686.S b/sysdeps/i386/i686/multiarch/memset-i686.S
new file mode 100644
index 0000000..e9a22b8
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memset-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memset.S b/sysdeps/i386/i686/multiarch/memset.S
deleted file mode 100644
index 8015d57..0000000
--- a/sysdeps/i386/i686/multiarch/memset.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Multiple versions of memset
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(memset)
-	.type	memset, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2_rep)
-2:	ret
-END(memset)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memset_ia32, @function; \
-	.globl __memset_ia32; \
-	.p2align 4; \
-	__memset_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memset_ia32, .-__memset_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memset_chk_ia32, @function; \
-	.globl __memset_chk_ia32; \
-	.p2align 4; \
-	__memset_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memset_chk_ia32, .-__memset_chk_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memset; __GI_memset = __memset_ia32
-# endif
-
-# undef strong_alias
-# define strong_alias(original, alias)
-#endif
-
-#include "../memset.S"
diff --git a/sysdeps/i386/i686/multiarch/memset.c b/sysdeps/i386/i686/multiarch/memset.c
new file mode 100644
index 0000000..57037dd
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memset.c>
diff --git a/sysdeps/i386/i686/multiarch/memset_chk.S b/sysdeps/i386/i686/multiarch/memset_chk.S
deleted file mode 100644
index 7be45e7..0000000
--- a/sysdeps/i386/i686/multiarch/memset_chk.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Multiple versions of __memset_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__memset_chk)
-	.type	__memset_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep)
-2:	ret
-END(__memset_chk)
-
-# ifdef SHARED
-strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
-	.section .gnu.warning.__memset_zero_constant_len_parameter
-	.string "memset used with constant zero length parameter; this could be due to transposed parameters"
-# else
-	.text
-	.type __memset_chk_sse2, @function
-	.p2align 4;
-__memset_chk_sse2:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2
-	cfi_endproc
-	.size __memset_chk_sse2, .-__memset_chk_sse2
-
-	.type __memset_chk_sse2_rep, @function
-	.p2align 4;
-__memset_chk_sse2_rep:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2_rep
-	cfi_endproc
-	.size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep
-
-	.type __memset_chk_ia32, @function
-	.p2align 4;
-__memset_chk_ia32:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_ia32
-	cfi_endproc
-	.size __memset_chk_ia32, .-__memset_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/rtld-memset.S b/sysdeps/i386/i686/multiarch/rtld-memset.S
new file mode 100644
index 0000000..fefbc63
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memset.S
@@ -0,0 +1 @@
+#include <sysdeps/i386/i686/memset.S>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
new file mode 100644
index 0000000..44fabed
--- /dev/null
+++ b/sysdeps/i386/multiarch/Makefile
@@ -0,0 +1,12 @@
+ifeq ($(subdir),csu)
+tests += test-multiarch
+gen-as-const-headers += ifunc-defines.sym
+endif
+
+ifeq ($(subdir),string)
+gen-as-const-headers += locale-defines.sym
+sysdep_routines += bzero-i386 bzero-i586 bzero-i686 \
+		   bzero-sse2 bzero-sse2-rep \
+		   memset-i386 memset-i586 memset-i686 \
+		   memset-sse2 memset-sse2-rep
+endif
diff --git a/sysdeps/i386/multiarch/bzero-i386.S b/sysdeps/i386/multiarch/bzero-i386.S
new file mode 100644
index 0000000..4a253d6
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/bzero-i386.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i386
+#endif
diff --git a/sysdeps/i386/multiarch/bzero-i586.S b/sysdeps/i386/multiarch/bzero-i586.S
new file mode 100644
index 0000000..2d5b61a
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i586.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/bzero.S>
diff --git a/sysdeps/i386/multiarch/bzero-i686.S b/sysdeps/i386/multiarch/bzero-i686.S
new file mode 100644
index 0000000..aaa36ce
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i686.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/bzero.S>
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S b/sysdeps/i386/multiarch/bzero-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2-rep.S
rename to sysdeps/i386/multiarch/bzero-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2.S b/sysdeps/i386/multiarch/bzero-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2.S
rename to sysdeps/i386/multiarch/bzero-sse2.S
diff --git a/sysdeps/i386/multiarch/bzero.c b/sysdeps/i386/multiarch/bzero.c
new file mode 100644
index 0000000..75fe9b8
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero.c
@@ -0,0 +1,63 @@
+/* Multiple versions of bzero.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+/* Redefine bzero so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef bzero
+# define bzero __redirect_bzero
+# include <string.h>
+# undef bzero
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_bzero) __bzero_i386 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_i586 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_i686 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_bzero) __bzero;
+extern void *bzero_ifunc (void) __asm__ ("__bzero");
+
+void *
+bzero_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	return __bzero_sse2_rep;
+      else
+	return __bzero_sse2;
+    }
+
+  if (USE_I686)
+    return __bzero_i686;
+  else if (USE_I586)
+    return __bzero_i586;
+  else
+    return __bzero_i386;
+}
+__asm__ (".type __bzero, %gnu_indirect_function");
+
+weak_alias (__bzero, bzero)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/ifunc-defines.sym b/sysdeps/i386/multiarch/ifunc-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/ifunc-defines.sym
rename to sysdeps/i386/multiarch/ifunc-defines.sym
diff --git a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
similarity index 94%
rename from sysdeps/i386/i686/multiarch/ifunc-impl-list.c
rename to sysdeps/i386/multiarch/ifunc-impl-list.c
index a6735a8..21d21ae 100644
--- a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -1,4 +1,4 @@
-/* Enumerate available IFUNC implementations of a function.  i686 version.
+/* Enumerate available IFUNC implementations of a function.  i386 version.
    Copyright (C) 2012-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -36,6 +36,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   size_t i = 0;
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/bcopy.S.  */
   IFUNC_IMPL (i, name, bcopy,
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
@@ -45,6 +46,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2),
 			      __bcopy_sse2_unaligned)
 	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/bzero.S.  */
   IFUNC_IMPL (i, name, bzero,
@@ -52,8 +54,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __bzero_sse2_rep)
 	      IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
 			      __bzero_sse2)
-	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ia32))
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I686, __bzero_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I586, __bzero_i586)
+	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_i386)
+#endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/memchr.S.  */
   IFUNC_IMPL (i, name, memchr,
 	      IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2),
@@ -101,6 +109,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
 			      __memrchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/memset_chk.S.  */
   IFUNC_IMPL (i, name, __memset_chk,
@@ -110,8 +119,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, __memset_chk,
 			      HAS_CPU_FEATURE (SSE2),
 			      __memset_chk_sse2)
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_I686, __memset_chk_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_I586, __memset_chk_i586)
 	      IFUNC_IMPL_ADD (array, i, __memset_chk, 1,
-			      __memset_chk_ia32))
+			      __memset_chk_i386)
+#endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memset.S.  */
   IFUNC_IMPL (i, name, memset,
@@ -119,8 +135,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memset_sse2_rep)
 	      IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
 			      __memset_sse2)
-	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ia32))
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I686,
+			      __memset_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I586,
+			      __memset_i586)
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_i386)
+#endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/rawmemchr.S.  */
   IFUNC_IMPL (i, name, rawmemchr,
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
@@ -371,6 +395,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
 #endif
+#endif
 
   return i;
 }
diff --git a/sysdeps/i386/i686/multiarch/locale-defines.sym b/sysdeps/i386/multiarch/locale-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/locale-defines.sym
rename to sysdeps/i386/multiarch/locale-defines.sym
diff --git a/sysdeps/i386/multiarch/memset-i386.S b/sysdeps/i386/multiarch/memset-i386.S
new file mode 100644
index 0000000..860c756
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/memset-i386.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memset-i586.S b/sysdeps/i386/multiarch/memset-i586.S
new file mode 100644
index 0000000..4c94fe4
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i586.S
@@ -0,0 +1,5 @@
+#define memset __memset_i586
+#define __memset_chk __memset_chk_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i586/memset.S>
diff --git a/sysdeps/i386/multiarch/memset-i686.S b/sysdeps/i386/multiarch/memset-i686.S
new file mode 100644
index 0000000..8d3462f
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i686.S
@@ -0,0 +1,5 @@
+#define memset __memset_i686
+#define __memset_chk __memset_chk_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i686/memset.S>
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/multiarch/memset-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2-rep.S
rename to sysdeps/i386/multiarch/memset-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/multiarch/memset-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2.S
rename to sysdeps/i386/multiarch/memset-sse2.S
diff --git a/sysdeps/i386/multiarch/memset.c b/sysdeps/i386/multiarch/memset.c
new file mode 100644
index 0000000..49d7839
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset.c
@@ -0,0 +1,63 @@
+/* Multiple versions of memset.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+/* Redefine memset so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memset
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memset) __memset_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i586 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i686 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memset) __memset;
+extern void *memset_ifunc (void) __asm__ ("__memset");
+
+void *
+memset_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	return __memset_sse2_rep;
+      else
+	return __memset_sse2;
+    }
+
+  if (USE_I686)
+    return __memset_i686;
+  else if (USE_I586)
+    return __memset_i586;
+  else
+    return __memset_i386;
+}
+__asm__ (".type __memset, %gnu_indirect_function");
+
+strong_alias (__memset, memset)
+#endif
diff --git a/sysdeps/i386/multiarch/memset_chk.c b/sysdeps/i386/multiarch/memset_chk.c
new file mode 100644
index 0000000..5e5c9b6
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset_chk.c
@@ -0,0 +1,101 @@
+/* Multiple versions of __memset_chk
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+# include <stddef.h>
+extern void * __memset_chk (void *, int, size_t, size_t);
+
+# ifdef SHARED
+extern __typeof (__memset_chk) __memset_chk_i386 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_i586 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_i686 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_sse2 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_sse2_rep attribute_hidden;
+
+#  include <init-arch.h>
+# else
+/* Redefine memset so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+#  undef memset
+#  define memset __redirect_memset
+#  include <string.h>
+#  undef memset
+
+extern __typeof (__redirect_memset) __memset_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i586 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i686 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden;
+
+#  include <init-arch.h>
+
+/* Due to
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10837
+   noreturn attribute disable tail call optimization.  Removes noreturn
+   attribute to enable tail call optimization.  */
+extern void *chk_fail (void) __asm__ ("__chk_fail") attribute_hidden;
+
+#define ifunc_chk(func, arch) \
+static void *							\
+func##_chk_##arch (void *dstpp, int c, size_t len,		\
+		   size_t dstlen)				\
+{								\
+  if (__glibc_unlikely (dstlen < len))				\
+    return chk_fail ();						\
+  return func##_##arch (dstpp, c, len);				\
+}
+
+#  if MINIMUM_ISA < 686
+ifunc_chk (__memset, i386)
+ifunc_chk (__memset, i586)
+#  else
+extern __typeof (__redirect_memset) __memset_chk_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_chk_i586 attribute_hidden;
+#  endif
+ifunc_chk (__memset, i686)
+ifunc_chk (__memset, sse2)
+ifunc_chk (__memset, sse2_rep)
+# endif
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern void *memset_chk_ifunc (void) __asm__ ("__memset_chk");
+
+void *
+memset_chk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memset_chk_sse2_rep;
+      else
+	return __memset_chk_sse2;
+    }
+
+  if (USE_I686)
+    return __memset_chk_i686;
+  else if (USE_I586)
+    return __memset_chk_i586;
+  else
+    return __memset_chk_i386;
+}
+__asm__ (".type __memset_chk, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/multiarch/test-multiarch.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/test-multiarch.c
rename to sysdeps/i386/multiarch/test-multiarch.c
