diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2849b944cccc2fd8d44063d62ddee59cf07ab01..f627ef7d157d61deec851408f33be1a2344d2f50 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2007-10-15  Alexandre Oliva  <aoliva@redhat.com>
+
+	PR middle-end/33706
+	* tree-inline.c (copy_bb): Use bsi_replace to replace a
+	__builtin_va_arg_pack-containing call stmt.
+
 2007-10-15  Razya Ladelsky  <razya@il.ibm.com>
 
         * matrix-reorg.c (gate_matrix_reorg): Don't comment out whole
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c541b3c88580f7e16346aa6d6e2fefb76143c705..7f09cddb89ca9521584fced0d203d99f04acaebe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-10-15  Alexandre Oliva  <aoliva@redhat.com>
+
+	PR middle-end/33706
+	* gcc.dg/va-arg-pack-2.c: New.
+
 2007-10-15  Jakub Jelinek  <jakub@redhat.com>
 
 	PR tree-optimization/33619
diff --git a/gcc/testsuite/gcc.dg/va-arg-pack-2.c b/gcc/testsuite/gcc.dg/va-arg-pack-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..417248a2a0140ba1dc29eb9a4c7a703b0d4de6aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/va-arg-pack-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void noreturn (int status, ...);
+
+extern inline __attribute ((always_inline)) void
+error (int status, ...)
+{
+  if (__builtin_constant_p (status))
+    noreturn (status, __builtin_va_arg_pack ());
+}
+
+void
+f (void)
+{
+  error (1);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index f575b27b82f8e489380b3d015f4f48d92fa95ad6..7ebfbcd4a6ce20a0b8e79d7e1a9c68cef64b348f 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -863,9 +863,18 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal
 		  if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR)
 		    call_ptr = &TREE_OPERAND (*call_ptr, 0);
 		  gcc_assert (*call_ptr == call);
-		  *call_ptr = new_call;
-		  stmt = *stmtp;
-		  update_stmt (stmt);
+		  if (call_ptr == stmtp)
+		    {
+		      bsi_replace (&copy_bsi, new_call, true);
+		      stmtp = bsi_stmt_ptr (copy_bsi);
+		      stmt = *stmtp;
+		    }
+		  else
+		    {
+		      *call_ptr = new_call;
+		      stmt = *stmtp;
+		      update_stmt (stmt);
+		    }
 		}
 	      else if (call
 		       && id->call_expr