--- gcc/builtins.c.jj	2010-11-19 20:56:54.000000000 +0100
+++ gcc/builtins.c	2010-11-24 22:23:41.000000000 +0100
@@ -8345,7 +8345,7 @@ fold_builtin_memset (location_t loc, tre
   if (integer_zerop (len))
     return omit_one_operand_loc (loc, type, dest, c);
 
-  if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
+  if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
     return NULL_TREE;
 
   var = dest;
@@ -8384,7 +8384,7 @@ fold_builtin_memset (location_t loc, tre
       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
 	return NULL_TREE;
 
-      cval = tree_low_cst (c, 1);
+      cval = TREE_INT_CST_LOW (c);
       cval &= 0xff;
       cval |= cval << 8;
       cval |= cval << 16;
--- gcc/testsuite/gcc.dg/pr46647.c.jj	2010-11-25 21:28:03.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr46647.c	2010-11-25 21:29:57.000000000 +0100
@@ -0,0 +1,29 @@
+/* PR middle-end/46647 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int a;
+
+int
+func1 (void)
+{
+  __builtin_memset (&a, -1, sizeof (a));
+  return 0;
+}
+
+int
+func2 (void)
+{
+  __builtin_memset (&a, 123, sizeof (a));
+  return 0;
+}
+
+int
+func3 (void)
+{
+  __builtin_memset (&a, 0, sizeof (a));
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "memset" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
