diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
index fc6be8eadef..6ca45f3b745 100644
--- a/gcc/ipa-split.cc
+++ b/gcc/ipa-split.cc
@@ -873,7 +873,6 @@ visit_bb (basic_block bb, basic_block return_bb,
       gimple *stmt = gsi_stmt (bsi);
       tree op;
       ssa_op_iter iter;
-      tree decl;
 
       if (is_gimple_debug (stmt))
 	continue;
@@ -899,33 +898,52 @@ visit_bb (basic_block bb, basic_block return_bb,
 	  can_split = false;
 	}
 
-      /* Check builtins that prevent splitting.  */
-      if (gimple_code (stmt) == GIMPLE_CALL
-	  && (decl = gimple_call_fndecl (stmt)) != NULL_TREE
-	  && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
-	switch (DECL_FUNCTION_CODE (decl))
-	  {
-	  /* FIXME: once we will allow passing non-parm values to split part,
-	     we need to be sure to handle correct builtin_stack_save and
-	     builtin_stack_restore.  At the moment we are safe; there is no
-	     way to store builtin_stack_save result in non-SSA variable
-	     since all calls to those are compiler generated.  */
-	  case BUILT_IN_APPLY:
-	  case BUILT_IN_APPLY_ARGS:
-	  case BUILT_IN_VA_START:
-	    if (dump_file && (dump_flags & TDF_DETAILS))
-	      fprintf (dump_file,
-		       "Cannot split: builtin_apply and va_start.\n");
-	    can_split = false;
-	    break;
-	  case BUILT_IN_EH_POINTER:
-	    if (dump_file && (dump_flags & TDF_DETAILS))
-	      fprintf (dump_file, "Cannot split: builtin_eh_pointer.\n");
-	    can_split = false;
-	    break;
-	  default:
-	    break;
-	  }
+      /* Check calls that would prevent splitting.  */
+      if (gimple_code (stmt) == GIMPLE_CALL)
+	{
+	  if (tree decl = gimple_call_fndecl (stmt))
+	    {
+	      /* Check builtins that would prevent splitting.  */
+	      if (fndecl_built_in_p (decl, BUILT_IN_NORMAL))
+		switch (DECL_FUNCTION_CODE (decl))
+		  {
+		  /* FIXME: once we will allow passing non-parm values to
+		     split part, we need to be sure to handle correct
+		     builtin_stack_save and builtin_stack_restore.  At the
+		     moment we are safe; there is no way to store
+		     builtin_stack_save result in non-SSA variable since all
+		     calls to those are compiler generated.  */
+		  case BUILT_IN_APPLY:
+		  case BUILT_IN_APPLY_ARGS:
+		  case BUILT_IN_VA_START:
+		    if (dump_file && (dump_flags & TDF_DETAILS))
+		      fprintf (dump_file,
+			       "Cannot split: builtin_apply and va_start.\n");
+		    can_split = false;
+		    break;
+		  case BUILT_IN_EH_POINTER:
+		    if (dump_file && (dump_flags & TDF_DETAILS))
+		      fprintf (dump_file,
+			       "Cannot split: builtin_eh_pointer.\n");
+		    can_split = false;
+		    break;
+		  default:
+		    break;
+		  }
+
+	      /* Calls that function has either the warning or error
+	         attribute on it should not be split off into another
+		 function.  */
+	      if (lookup_attribute ("warning", DECL_ATTRIBUTES (decl))
+		   || lookup_attribute ("error", DECL_ATTRIBUTES (decl)))
+		{
+		  if (dump_file && (dump_flags & TDF_DETAILS))
+		    fprintf (dump_file,
+			     "Cannot split: warning or error attribute.\n");
+		  can_split = false;
+		}
+	    }
+	}
 
       FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
 	bitmap_set_bit (set_ssa_names, SSA_NAME_VERSION (op));
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr101941-1.c b/gcc/testsuite/gcc.c-torture/compile/pr101941-1.c
new file mode 100644
index 00000000000..0481a3835a6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr101941-1.c
@@ -0,0 +1,50 @@
+/* { dg-additional-options "-fconserve-stack" } */
+
+/* Check to make sure that if
+   rfc4106_set_hash_subkey gets split,
+   the error function does not gets split away
+   from the if statement conditionalizing it. */
+
+struct crypto_aes_ctx {
+  char key_dec[128];
+};
+
+int rfc4106_set_hash_subkey_hash_subkey;
+
+void __write_overflow(void)__attribute__((__error__("")));
+void __write_overflow1(void);
+void aes_encrypt(void*);
+
+void fortify_panic(const char*) __attribute__((__noreturn__)) ;
+
+char *rfc4106_set_hash_subkey(struct crypto_aes_ctx *ctx) {
+  void *a = &ctx->key_dec[0];
+  unsigned p_size =  __builtin_object_size(a, 0);
+#ifdef __OPTIMIZE__
+  if (p_size < 16) {
+    __write_overflow1();
+    fortify_panic(__func__);
+  }
+  if (p_size < 32) {
+    __write_overflow();
+    fortify_panic(__func__);
+  }
+#endif
+  aes_encrypt(ctx);
+  return ctx->key_dec;
+}
+
+char *(*gg)(struct crypto_aes_ctx *) = rfc4106_set_hash_subkey;
+
+void a(void)
+{
+  struct crypto_aes_ctx ctx;
+  rfc4106_set_hash_subkey(&ctx);
+}
+void b(void)
+{
+  struct crypto_aes_ctx ctx;
+  ctx.key_dec[0] = 0;
+  rfc4106_set_hash_subkey(&ctx);
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101941-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101941-1.c
new file mode 100644
index 00000000000..a1a342a253a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101941-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fconserve-stack -fdump-tree-optimized" } */
+/* Check to make sure that if
+   rfc4106_set_hash_subkey gets split,
+   the error function does not gets split away
+   from the if statement conditionalizing it.
+   Checking this via the scan tree also. */
+struct crypto_aes_ctx {
+  char key_dec[128];
+};
+
+int rfc4106_set_hash_subkey_hash_subkey;
+
+void __write_overflow(void)__attribute__((__error__("")));
+void __write_overflow1(void);
+void aes_encrypt(void*);
+
+void fortify_panic(const char*) __attribute__((__noreturn__)) ;
+
+char *rfc4106_set_hash_subkey(struct crypto_aes_ctx *ctx) {
+  void *a = &ctx->key_dec[0];
+  unsigned p_size =  __builtin_object_size(a, 0);
+#ifdef __OPTIMIZE__
+  if (p_size < 16) {
+    __write_overflow1();
+    fortify_panic(__func__);
+  }
+  if (p_size < 32) {
+    __write_overflow();
+    fortify_panic(__func__);
+  }
+#endif
+  aes_encrypt(ctx);
+  return ctx->key_dec;
+}
+
+char *(*gg)(struct crypto_aes_ctx *) = rfc4106_set_hash_subkey;
+
+void a(void)
+{
+  struct crypto_aes_ctx ctx;
+  rfc4106_set_hash_subkey(&ctx);
+}
+void b(void)
+{
+  struct crypto_aes_ctx ctx;
+  ctx.key_dec[0] = 0;
+  rfc4106_set_hash_subkey(&ctx);
+}
+
+/* This testcase should still split out one of the above basic blocks dealing
+   with __write_overflow. */
+/* { dg-final { scan-tree-dump-times "Function rfc4106_set_hash_subkey.part" 1 "optimized" } } */
