summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog97
-rw-r--r--manual/examples/mkfsock.c1
-rw-r--r--posix/regcomp.c249
-rw-r--r--posix/regex.c6
-rw-r--r--posix/regex_internal.c146
-rw-r--r--posix/regex_internal.h6
-rw-r--r--posix/regexec.c156
-rw-r--r--sysdeps/i386/i586/strlen.S4
-rw-r--r--sysdeps/i386/i686/strcmp.S7
9 files changed, 371 insertions, 301 deletions
diff --git a/ChangeLog b/ChangeLog
index 034ac72939..f67e797c14 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,100 @@
+2002-03-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* manual/examples/mkfsock.c: Include <string.h> as well.
+	Patch by Alain De Carolis <alaind@wseurope.com>.
+
+2002-03-06  Isamu Hasegawa  <isamu@yamato.ibm.com>
+
+	* posix/regexec.c (re_match): Fix incorrect register sizes.
+	(re_search): Likewise.
+
+2002-03-05  Isamu Hasegawa  <isamu@yamato.ibm.com>
+
+	* posix/regcomp.c (regfree): Remove a disused condition.
+	* posix/regex_internal.c (re_acquire_state): Likewise.
+	(re_acquire_state_context): Likewise.
+	(register_state): Remove a redundant malloc invocation.
+	* posix/regex_internal.h: (re_state_table_entry): Simplify
+	the structure.
+
+2002-03-05  Isamu Hasegawa  <isamu@yamato.ibm.com>
+
+	* posix/regcomp.c (regcomp): Add __builtin_expect to error
+	handling conditions.
+	(regerror): Likewise.
+	(regfree): Likewise.
+	(re_compile_internal): Likewise.
+	(init_dfa): Likewise.
+	(init_word_char): Likewise.
+	(create_initial_state): Likewise.
+	(analyze): Likewise.
+	(analyze_tree): Likewise.
+	(duplicate_node): Likewise.
+	(calc_eclosure): Likewise.
+	(calc_eclosure_iter): Likewise.
+	(parse): Likewise.
+	(parse_reg_exp): Likewise.
+	(parse_branch): Likewise.
+	(parse_expression): Likewise.
+	(parse_subexp): Likewise.
+	(parse_dup_op): Likewise.
+	(parse_bracket_exp): Likewise.
+	(build_equiv_class): Likewise.
+	(build_charclass): Likewise.
+	(build_word_op): Likewise.
+	(fetch_number): Likewise.
+	(create_tree): Likewise.
+	(duplicate_tree): Likewise.
+	* posix/regex.c (BE): New macro.
+	* posix/regexec.c (re_match): Add __builtin_expect to error
+	handling conditions.
+	(re_match_2): Likewise.
+	(re_search): Likewise.
+	(re_search_internal): Likewise.
+	(check_matching): Likewise.
+	(proceed_next_node): Likewise.
+	(set_regs): Likewise.
+	(sift_states_backward): Likewise.
+	(add_epsilon_backreference): Likewise.
+	(transit_state): Likewise.
+	(transit_state_sb): Likewise.
+	(transit_state_mb): Likewise.
+	(transit_state_bkref): Likewise.
+	(transit_state_bkref_loop): Likewise.
+	(build_trtable): Likewise.
+	(group_nodes_into_DFAstates): Likewise.
+	(match_ctx_init): Likewise.
+	(match_ctx_add_entry): Likewise.
+	* posix/regex_internal.c (re_string_construct): Add __builtin_expect
+	to error handling conditions.
+	(re_string_construct_toupper): Likewise.
+	(build_wcs_buffer): Likewise.
+	(build_wcs_upper_buffer): Likewise.
+	(build_upper_buffer): Likewise.
+	(re_string_translate_buffer): Likewise.
+	(re_node_set_alloc): Likewise.
+	(re_node_set_init_1): Likewise.
+	(re_node_set_init_2): Likewise.
+	(re_node_set_init_copy): Likewise.
+	(re_node_set_intersect): Likewise.
+	(re_node_set_init_union): Likewise.
+	(re_node_set_merge): Likewise.
+	(re_node_set_insert): Likewise.
+	(re_dfa_add_node): Likewise.
+	(re_acquire_state): Likewise.
+	(re_acquire_state_context): Likewise.
+	(create_new_state_common): Likewise.
+	(register_state): Likewise.
+	(create_ci_new_state): Likewise.
+	(create_cd_new_state): Likewise.
+	(re_string_context_at): Remove redundant condition.
+
+2002-01-16  Roger Sayle  <roger@eyesopen.com>
+
+	* sysdeps/i386/i686/strcmp.S: Avoid unconditional jump to a ret.
+
+	* sysdeps/i386/i586/strlen.S: Fix typo in comment.
+
 2002-03-11  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/i386/elf/configure.in: Fix comment.
diff --git a/manual/examples/mkfsock.c b/manual/examples/mkfsock.c
index 1ecabb95cf..615ecd8684 100644
--- a/manual/examples/mkfsock.c
+++ b/manual/examples/mkfsock.c
@@ -2,6 +2,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 44f55f24af..930e8a61b5 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -424,7 +424,7 @@ regcomp (preg, pattern, cflags)
 
   /* Try to allocate space for the fastmap.  */
   preg->fastmap = re_malloc (char, SBC_MAX);
-  if (preg->fastmap == NULL)
+  if (BE (preg->fastmap == NULL, 0))
     return REG_ESPACE;
 
   syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
@@ -450,11 +450,11 @@ regcomp (preg, pattern, cflags)
     ret = REG_EPAREN;
 
   /* We have already checked preg->fastmap != NULL.  */
-  if (ret == REG_NOERROR)
+  if (BE (ret == REG_NOERROR, 1))
     {
       /* Compute the fastmap now, since regexec cannot modify the pattern
 	 buffer.  */
-      if (re_compile_fastmap (preg) == -2)
+      if (BE (re_compile_fastmap (preg) == -2, 0))
 	{
 	  /* Some error occurred while computing the fastmap, just forget
 	     about it.  */
@@ -482,9 +482,9 @@ regerror (errcode, preg, errbuf, errbuf_size)
   const char *msg;
   size_t msg_size;
 
-  if (errcode < 0
-      || errcode >= (int) (sizeof (re_error_msgid_idx)
-			   / sizeof (re_error_msgid_idx[0])))
+  if (BE (errcode < 0
+          || errcode >= (int) (sizeof (re_error_msgid_idx)
+                               / sizeof (re_error_msgid_idx[0])), 0))
     /* Only error codes returned by the rest of the code should be passed
        to this routine.  If we are given anything else, or if other regex
        code generates an invalid error code, then the program has a bug.
@@ -495,9 +495,9 @@ regerror (errcode, preg, errbuf, errbuf_size)
 
   msg_size = strlen (msg) + 1; /* Includes the null.  */
 
-  if (errbuf_size != 0)
+  if (BE (errbuf_size != 0, 1))
     {
-      if (msg_size > errbuf_size)
+      if (BE (msg_size > errbuf_size, 0))
         {
 #if defined HAVE_MEMPCPY || defined _LIBC
 	  *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
@@ -524,7 +524,7 @@ regfree (preg)
 {
   int i, j;
   re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  if (dfa != NULL)
+  if (BE (dfa != NULL, 1))
     {
       re_free (dfa->subexps);
 
@@ -565,25 +565,20 @@ regfree (preg)
       for (i = 0; i <= dfa->state_hash_mask; ++i)
         {
           struct re_state_table_entry *entry = dfa->state_table + i;
-          if (entry->alloc == 0)
-            re_free (entry->entry.state);
-          else
+          for (j = 0; j < entry->num; ++j)
             {
-              for (j = 0; j < entry->num; ++j)
+              re_dfastate_t *state = entry->array[j];
+              if (state->entrance_nodes != &state->nodes)
                 {
-                  re_dfastate_t *state = entry->entry.array[j];
-                  if (state->entrance_nodes != &state->nodes)
-                    {
-                      re_node_set_free (state->entrance_nodes);
-                      re_free (state->entrance_nodes);
-                    }
-                  re_node_set_free (&state->nodes);
-                  re_free (state->trtable);
-                  re_free (state->trtable_search);
-                  re_free (state);
+                  re_node_set_free (state->entrance_nodes);
+                  re_free (state->entrance_nodes);
                 }
-              re_free (entry->entry.array);
+              re_node_set_free (&state->nodes);
+              re_free (state->trtable);
+              re_free (state->trtable_search);
+              re_free (state);
             }
+          re_free (entry->array);
         }
       re_free (dfa->state_table);
 
@@ -688,7 +683,7 @@ re_compile_internal (preg, pattern, length, syntax)
   preg->used = sizeof (re_dfa_t);
 
   err = init_dfa (dfa, length);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     {
       re_free (dfa);
       preg->buffer = NULL;
@@ -701,7 +696,7 @@ re_compile_internal (preg, pattern, length, syntax)
   else
     err = re_string_construct (&regexp, pattern, length, preg->translate);
 
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     {
       re_free (dfa);
       preg->buffer = NULL;
@@ -711,18 +706,18 @@ re_compile_internal (preg, pattern, length, syntax)
   /* Parse the regular expression, and build a structure tree.  */
   preg->re_nsub = 0;
   dfa->str_tree = parse (&regexp, preg, syntax, &err);
-  if (dfa->str_tree == NULL)
+  if (BE (dfa->str_tree == NULL, 0))
     goto re_compile_internal_free_return;
 
   /* Analyze the tree and collect information which is necessary to
      create the dfa.  */
   err = analyze (dfa);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     goto re_compile_internal_free_return;
 
   /* Then create the initial state of the dfa.  */
   err = create_initial_state (dfa);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     goto re_compile_internal_free_return;
 
  re_compile_internal_free_return:
@@ -759,7 +754,8 @@ init_dfa (dfa, pat_len)
   dfa->subexps = re_malloc (re_subexp_t, dfa->subexps_alloc);
   dfa->word_char = NULL;
 
-  if (dfa->nodes == NULL || dfa->state_table == NULL || dfa->subexps == NULL)
+  if (BE (dfa->nodes == NULL || dfa->state_table == NULL
+          || dfa->subexps == NULL, 0))
     {
       /* We don't bother to free anything which was allocated.  Very
 	 soon the process will go down anyway.  */
@@ -781,7 +777,7 @@ init_word_char (dfa)
 {
   int i, j, ch;
   dfa->word_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
-  if (dfa->word_char == NULL)
+  if (BE (dfa->word_char == NULL, 0))
     return REG_ESPACE;
   for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
     for (j = 0; j < UINT_BITS; ++j, ++ch)
@@ -816,7 +812,7 @@ create_initial_state (dfa)
   first = dfa->str_tree->first;
   dfa->init_node = first;
   err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   /* The back-references which are in initial states can epsilon transit,
@@ -852,7 +848,7 @@ create_initial_state (dfa)
   /* It must be the first time to invoke acquire_state.  */
   dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
   /* We don't check ERR here, since the initial state must not be NULL.  */
-  if (dfa->init_state == NULL)
+  if (BE (dfa->init_state == NULL, 0))
     return err;
   if (dfa->init_state->has_constraint)
     {
@@ -864,8 +860,8 @@ create_initial_state (dfa)
                                                          &init_nodes,
                                                          CONTEXT_NEWLINE
                                                          | CONTEXT_BEGBUF);
-      if (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-          || dfa->init_state_begbuf == NULL)
+      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+              || dfa->init_state_begbuf == NULL, 0))
         return err;
     }
   else
@@ -892,8 +888,8 @@ analyze (dfa)
   dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  if (dfa->firsts == NULL || dfa->nexts == NULL || dfa->edests == NULL
-      || dfa->eclosures == NULL || dfa->inveclosures == NULL)
+  if (BE (dfa->firsts == NULL || dfa->nexts == NULL || dfa->edests == NULL
+          || dfa->eclosures == NULL || dfa->inveclosures == NULL, 0))
     return REG_ESPACE;
   /* Initialize them.  */
   for (i = 0; i < dfa->nodes_len; ++i)
@@ -906,7 +902,7 @@ analyze (dfa)
     }
 
   ret = analyze_tree (dfa, dfa->str_tree);
-  if (ret == REG_NOERROR)
+  if (BE (ret == REG_NOERROR, 1))
     {
       ret = calc_eclosure (dfa);
       if (ret == REG_NOERROR)
@@ -935,14 +931,14 @@ analyze_tree (dfa, node)
   if (node->left != NULL)
     {
       ret = analyze_tree (dfa, node->left);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   /* Calculate "first" etc. for the right child.  */
   if (node->right != NULL)
     {
       ret = analyze_tree (dfa, node->right);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -1158,7 +1154,7 @@ duplicate_node (new_idx, dfa, org_idx, constraint)
      we correct `entity' to real entity in calc_inveclosures(). */
   dup.opr.ctx_info = malloc (sizeof (*dup.opr.ctx_info));
   dup_idx = re_dfa_add_node (dfa, dup, 1);
-  if (dup.opr.ctx_info == NULL || dup_idx == -1)
+  if (BE (dup.opr.ctx_info == NULL || dup_idx == -1, 0))
     return REG_ESPACE;
   dup.opr.ctx_info->entity = org_idx;
   dup.opr.ctx_info->bkref_eclosure = NULL;
@@ -1167,15 +1163,15 @@ duplicate_node (new_idx, dfa, org_idx, constraint)
   dfa->firsts[dup_idx] = dfa->firsts[org_idx];
   dfa->nexts[dup_idx] = dfa->nexts[org_idx];
   err = re_node_set_init_copy (dfa->edests + dup_idx, dfa->edests + org_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   /* Since we don't duplicate epsilon nodes, epsilon closure have
      only itself.  */
   err = re_node_set_init_1 (dfa->eclosures + dup_idx, dup_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   err = re_node_set_init_1 (dfa->inveclosures + dup_idx, dup_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   /* Then we must update inveclosure for this node.
      We process them at last part of calc_eclosure(),
@@ -1241,7 +1237,7 @@ calc_eclosure (dfa)
         continue;
       /* Calculate epsilon closure of `node_idx'.  */
       err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
 
       if (dfa->eclosures[node_idx].nelem == 0)
@@ -1265,7 +1261,7 @@ calc_eclosure (dfa)
          the next node. Since it may epsilon transit.  */
       /* Note: duplicate_node() may realloc dfa->eclosures, etc.  */
       bkref_eclosure = re_malloc (re_node_set, 1);
-      if (bkref_eclosure == NULL)
+      if (BE (bkref_eclosure == NULL, 0))
 	return REG_ESPACE;
       re_node_set_init_empty (bkref_eclosure);
       constraint = dfa->nodes[idx].constraint;
@@ -1277,7 +1273,7 @@ calc_eclosure (dfa)
               reg_errcode_t err;
               err = duplicate_node (&dest_node_idx, dfa, dest_node_idx,
                                     constraint);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return err;
             }
           re_node_set_insert (bkref_eclosure, dest_node_idx);
@@ -1301,7 +1297,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
   int i, max, incomplete = 0;
   re_node_set eclosure;
   err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   /* This indicates that we are calculating this node now.
@@ -1329,7 +1325,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
         if (dfa->eclosures[edest].nelem == 0)
           {
             err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);
-            if (err != REG_NOERROR)
+            if (BE (err != REG_NOERROR, 0))
               return err;
           }
         else
@@ -1356,7 +1352,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
             int dup_dest;
             reg_errcode_t err;
             err = duplicate_node (&dup_dest, dfa, dest, constraint);
-            if (err != REG_NOERROR)
+            if (BE (err != REG_NOERROR, 0))
               return err;
             if (dest != dup_dest)
               {
@@ -1716,7 +1712,7 @@ parse (regexp, preg, syntax, err)
   int new_idx;
   current_token = fetch_token (regexp, syntax);
   tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
   new_idx = re_dfa_add_node (dfa, current_token, 0);
   eor = create_tree (NULL, NULL, 0, new_idx);
@@ -1724,7 +1720,7 @@ parse (regexp, preg, syntax, err)
     root = create_tree (tree, eor, CONCAT, 0);
   else
     root = eor;
-  if (new_idx == -1 || eor == NULL || root == NULL)
+  if (BE (new_idx == -1 || eor == NULL || root == NULL, 0))
     return *err = REG_ESPACE, NULL;
   return root;
 }
@@ -1751,7 +1747,7 @@ parse_reg_exp (regexp, preg, token, syntax, nest, err)
   bin_tree_t *tree, *branch = NULL;
   int new_idx;
   tree = parse_branch (regexp, preg, token, syntax, nest, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
 
   while (token->type == OP_ALT)
@@ -1763,14 +1759,14 @@ parse_reg_exp (regexp, preg, token, syntax, nest, err)
           && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
         {
           branch = parse_branch (regexp, preg, token, syntax, nest, err);
-          if (*err != REG_NOERROR && branch == NULL)
+          if (BE (*err != REG_NOERROR && branch == NULL, 0))
             {
               free_bin_tree (tree);
               return NULL;
             }
         }
       tree = create_tree (tree, branch, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
   return tree;
@@ -1796,14 +1792,14 @@ parse_branch (regexp, preg, token, syntax, nest, err)
 {
   bin_tree_t *tree, *exp;
   tree = parse_expression (regexp, preg, token, syntax, nest, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
 
   while (token->type != OP_ALT && token->type != END_OF_RE
          && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
     {
       exp = parse_expression (regexp, preg, token, syntax, nest, err);
-      if (*err != REG_NOERROR && exp == NULL)
+      if (BE (*err != REG_NOERROR && exp == NULL, 0))
         {
           free_bin_tree (tree);
           return NULL;
@@ -1844,7 +1840,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
     case CHARACTER:
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
 #ifdef RE_ENABLE_I18N
       if (MB_CUR_MAX > 1)
@@ -1857,7 +1853,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
               new_idx = re_dfa_add_node (dfa, *token, 0);
               mbc_remain = create_tree (NULL, NULL, 0, new_idx);
               tree = create_tree (tree, mbc_remain, CONCAT, 0);
-              if (new_idx == -1 || mbc_remain == NULL || tree == NULL)
+              if (BE (new_idx == -1 || mbc_remain == NULL || tree == NULL, 0))
                 return *err = REG_ESPACE, NULL;
             }
 	}
@@ -1865,24 +1861,24 @@ parse_expression (regexp, preg, token, syntax, nest, err)
       break;
     case OP_OPEN_SUBEXP:
       tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_OPEN_BRACKET:
       tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_BACK_REF:
-      if (preg->re_nsub < token->opr.idx
-          || dfa->subexps[token->opr.idx - 1].end == -1)
+      if (BE (preg->re_nsub < token->opr.idx
+              || dfa->subexps[token->opr.idx - 1].end == -1, 0))
         {
           *err = REG_ESUBREG;
           return NULL;
         }
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       ++dfa->nbackref;
       dfa->has_mb_node = 1;
@@ -1911,14 +1907,14 @@ parse_expression (regexp, preg, token, syntax, nest, err)
       token->type = CHARACTER;
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       break;
     case ANCHOR:
       if (dfa->word_char == NULL)
         {
           *err = init_word_char (dfa);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
       if (token->opr.ctx_type == WORD_DELIM)
@@ -1934,15 +1930,16 @@ parse_expression (regexp, preg, token, syntax, nest, err)
           token->type = OP_ALT;
           new_idx = re_dfa_add_node (dfa, *token, 0);
           tree = create_tree (tree_first, tree_last, 0, new_idx);
-          if (idx_first == -1 || idx_last == -1 || new_idx == -1
-              || tree_first == NULL || tree_last == NULL || tree == NULL)
+          if (BE (idx_first == -1 || idx_last == -1 || new_idx == -1
+                  || tree_first == NULL || tree_last == NULL
+                  || tree == NULL, 0))
             return *err = REG_ESPACE, NULL;
         }
       else
         {
           new_idx = re_dfa_add_node (dfa, *token, 0);
           tree = create_tree (NULL, NULL, 0, new_idx);
-          if (new_idx == -1 || tree == NULL)
+          if (BE (new_idx == -1 || tree == NULL, 0))
             return *err = REG_ESPACE, NULL;
         }
       /* We must return here, since ANCHORs can't be followed
@@ -1954,19 +1951,19 @@ parse_expression (regexp, preg, token, syntax, nest, err)
     case OP_PERIOD:
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       if (MB_CUR_MAX > 1)
         dfa->has_mb_node = 1;
       break;
     case OP_WORD:
       tree = build_word_op (dfa, 0, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_NOTWORD:
       tree = build_word_op (dfa, 1, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_ALT:
@@ -1988,7 +1985,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
          || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
       tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
 
@@ -2020,7 +2017,7 @@ parse_sub_exp (regexp, preg, token, syntax, nest, err)
       re_subexp_t *new_array;
       dfa->subexps_alloc *= 2;
       new_array = re_realloc (dfa->subexps, re_subexp_t, dfa->subexps_alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
 	{
 	  dfa->subexps_alloc /= 2;
 	  *err = REG_ESPACE;
@@ -2036,17 +2033,17 @@ parse_sub_exp (regexp, preg, token, syntax, nest, err)
   if (token->type == OP_CLOSE_SUBEXP)
     {
       tree = create_tree (NULL, NULL, SUBEXP, 0);
-      if (tree == NULL)
+      if (BE (tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       dfa->subexps[cur_nsub].end = dfa->nodes_len;
     }
   else
     {
       tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       dfa->subexps[cur_nsub].end = dfa->nodes_len;
-      if (token->type != OP_CLOSE_SUBEXP)
+      if (BE (token->type != OP_CLOSE_SUBEXP, 0))
         {
           free_bin_tree (tree);
           *err = REG_BADPAT;
@@ -2089,13 +2086,14 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
             }
           end = start; /* We treat "{n}" as "{n,n}".  */
         }
-      else if (start == -2 || token->type != CHARACTER || token->opr.c != ',')
+      else if (BE (start == -2 || token->type != CHARACTER
+                   || token->opr.c != ',', 0))
         /* Invalid sequence.  */
         goto parse_dup_op_invalid_interval;
       else
         {
           end = fetch_number (regexp, token, syntax);
-          if (end == -2 || token->type != OP_CLOSE_DUP_NUM)
+          if (BE (end == -2 || token->type != OP_CLOSE_DUP_NUM, 0))
             /* Invalid sequence.  */
             goto parse_dup_op_invalid_interval;
         }
@@ -2106,7 +2104,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
           {
             work_tree = duplicate_tree (elem, dfa);
             tree = create_tree (tree, work_tree, CONCAT, 0);
-            if (work_tree == NULL || tree == NULL)
+            if (BE (work_tree == NULL || tree == NULL, 0))
               goto parse_dup_op_espace;
           }
 
@@ -2120,15 +2118,15 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               work_tree = create_tree (elem, NULL, 0, new_idx);
               tree = create_tree (tree, work_tree, CONCAT, 0);
-              if (elem == NULL || new_idx == -1 || work_tree == NULL
-                  || tree == NULL)
+              if (BE (elem == NULL || new_idx == -1 || work_tree == NULL
+                      || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           else
             {
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               tree = create_tree (elem, NULL, 0, new_idx);
-              if (new_idx == -1 || tree == NULL)
+              if (BE (new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
         }
@@ -2142,21 +2140,21 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               elem = create_tree (elem, NULL, 0, new_idx);
               tree = create_tree (tree, elem, CONCAT, 0);
-              if (elem == NULL || new_idx == -1 || tree == NULL)
+              if (BE (elem == NULL || new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           else
             {
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               tree = elem = create_tree (elem, NULL, 0, new_idx);
-              if (new_idx == -1 || tree == NULL)
+              if (BE (new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           for (i = 1; i < end - start; ++i)
             {
               work_tree = duplicate_tree (elem, dfa);
               tree = create_tree (tree, work_tree, CONCAT, 0);
-              if (work_tree == NULL || tree == NULL)
+              if (BE (work_tree == NULL || tree == NULL, 0))
                 return *err = REG_ESPACE, NULL;
             }
         }
@@ -2165,7 +2163,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
     {
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (tree, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
   *token = fetch_token (regexp, syntax);
@@ -2177,7 +2175,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
   return NULL;
 
  parse_dup_op_invalid_interval:
-  if (!(syntax & RE_INVALID_INTERVAL_ORD))
+  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
     {
       *err = REG_EBRACE;
       return NULL;
@@ -2341,7 +2339,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
           new_array_end = re_realloc (mbcset->range_ends, uint32_t,
                                       new_nranges);
 
-          if (new_array_start == NULL || new_array_end == NULL)
+          if (BE (new_array_start == NULL || new_array_end == NULL, 0))
             return REG_ESPACE;
 
           mbcset->range_starts = new_array_start;
@@ -2349,16 +2347,17 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
 	  *range_alloc = new_nranges;
         }
 
-      if (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-          || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS)
+      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+              || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+              0))
         return REG_ERANGE;
 
       start_collseq = lookup_collation_sequence_value (start_elem);
       end_collseq = lookup_collation_sequence_value (end_elem);
       /* Check start/end collation sequence values.  */
-      if (start_collseq == UINT_MAX || end_collseq == UINT_MAX)
+      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
         return REG_ECOLLATE;
-      if ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq)
+      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
         return REG_ERANGE;
 
       /* Got valid collation sequence values, add them as a new entry.  */
@@ -2429,7 +2428,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
                  if *alloc == 0.  */
               mbcset->coll_syms = re_realloc (mbcset->coll_syms, int32_t,
                                               *coll_sym_alloc);
-              if (mbcset->coll_syms == NULL)
+              if (BE (mbcset->coll_syms == NULL, 0))
                 return REG_ESPACE;
             }
           mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
@@ -2438,7 +2437,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       else
 #endif
         {
-          if (strlen (name) != 1)
+          if (BE (strlen (name) != 1, 0))
             return REG_ECOLLATE;
           else
             {
@@ -2472,14 +2471,14 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
 #endif
   sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-  if (sbcset == NULL || mbcset == NULL)
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
     {
       *err = REG_ESPACE;
       return NULL;
     }
 
   token_len = peek_token_bracket (token, regexp, syntax);
-  if (token->type == END_OF_RE)
+  if (BE (token->type == END_OF_RE, 0))
     {
       re_free (sbcset);
       free_charset (mbcset);
@@ -2494,7 +2493,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
         bitset_set (sbcset, '\0');
       re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
       token_len = peek_token_bracket (token, regexp, syntax);
-      if (token->type == END_OF_RE)
+      if (BE (token->type == END_OF_RE, 0))
         {
           re_free (sbcset);
           free_charset (mbcset);
@@ -2523,11 +2522,11 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       start_elem.opr.name = start_name_buf;
       ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
                                    syntax);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         goto parse_bracket_exp_espace;
 
       token_len = peek_token_bracket (token, regexp, syntax);
-      if (token->type == END_OF_RE)
+      if (BE (token->type == END_OF_RE, 0))
         {
           re_free (sbcset);
           free_charset (mbcset);
@@ -2538,7 +2537,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
         {
           re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
           token_len2 = peek_token_bracket (&token2, regexp, syntax);
-          if (token->type == END_OF_RE)
+          if (BE (token->type == END_OF_RE, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2560,11 +2559,11 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
           end_elem.opr.name = end_name_buf;
           ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
                                        dfa, syntax);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             goto parse_bracket_exp_espace;
 
           token_len = peek_token_bracket (token, regexp, syntax);
-          if (token->type == END_OF_RE)
+          if (BE (token->type == END_OF_RE, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2573,7 +2572,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             }
           *err = build_range_exp (mbcset, sbcset, &range_alloc, &start_elem,
 				  &end_elem);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2597,7 +2596,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
                   /* Use realloc since array is NULL if *alloc == 0.  */
                   mbcset->mbchars = re_realloc (mbcset->mbchars, wchar_t,
                                                 mbchar_alloc);
-                  if (mbcset->mbchars == NULL)
+                  if (BE (mbcset->mbchars == NULL, 0))
                     goto parse_bracket_exp_espace;
                 }
               mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
@@ -2605,7 +2604,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case EQUIV_CLASS:
               *err = build_equiv_class (mbcset, sbcset, &equiv_class_alloc,
 					start_elem.opr.name);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 {
                   re_free (sbcset);
                   free_charset (mbcset);
@@ -2615,7 +2614,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case COLL_SYM:
               *err = build_collating_symbol (mbcset, sbcset, &coll_sym_alloc,
 					     start_elem.opr.name);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 {
                   re_free (sbcset);
                   free_charset (mbcset);
@@ -2625,7 +2624,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case CHAR_CLASS:
               ret = build_charclass (mbcset, sbcset, &char_class_alloc,
 				     start_elem.opr.name);
-              if (ret != REG_NOERROR)
+              if (BE (ret != REG_NOERROR, 0))
                goto parse_bracket_exp_espace;
               break;
             default:
@@ -2648,7 +2647,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
   br_token.opr.sbcset = sbcset;
   new_idx = re_dfa_add_node (dfa, br_token, 0);
   work_tree = create_tree (NULL, NULL, 0, new_idx);
-  if (new_idx == -1 || work_tree == NULL)
+  if (BE (new_idx == -1 || work_tree == NULL, 0))
     goto parse_bracket_exp_espace;
 
   if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
@@ -2662,13 +2661,13 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       dfa->has_mb_node = 1;
       new_idx = re_dfa_add_node (dfa, br_token, 0);
       mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || mbc_tree == NULL)
+      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
         goto parse_bracket_exp_espace;
       /* Then join them by ALT node.  */
       alt_token.type = OP_ALT;
       new_idx = re_dfa_add_node (dfa, alt_token, 0);
       work_tree = create_tree (work_tree, mbc_tree, 0, new_idx);
-      if (new_idx != -1 && mbc_tree != NULL)
+      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
         return work_tree;
     }
   else
@@ -2787,7 +2786,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
       indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
                                                 _NL_COLLATE_INDIRECTMB);
       idx1 = findidx (&cp);
-      if (idx1 == 0 || cp < name + strlen (name))
+      if (BE (idx1 == 0 || cp < name + strlen (name), 0))
         /* This isn't a valid character.  */
         return REG_ECOLLATE;
 
@@ -2825,7 +2824,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
           /* Use realloc since the array is NULL if *alloc == 0.  */
           mbcset->equiv_classes = re_realloc (mbcset->equiv_classes, int32_t,
                                               *equiv_class_alloc);
-          if (mbcset->equiv_classes == NULL)
+          if (BE (mbcset->equiv_classes == NULL, 0))
             return REG_ESPACE;
         }
       mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
@@ -2833,7 +2832,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
   else
 #endif
     {
-      if (strlen (name) != 1)
+      if (BE (strlen (name) != 1, 0))
         return REG_ECOLLATE;
       bitset_set (sbcset, name[0]);
     }
@@ -2864,7 +2863,7 @@ build_charclass (mbcset, sbcset, char_class_alloc, name)
       /* Use realloc since array is NULL if *alloc == 0.  */
       mbcset->char_classes = re_realloc (mbcset->char_classes, wctype_t,
                                          *char_class_alloc);
-      if (mbcset->char_classes == NULL)
+      if (BE (mbcset->char_classes == NULL, 0))
         return REG_ESPACE;
     }
 
@@ -2922,7 +2921,7 @@ build_word_op (dfa, not, err)
 
   sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-  if (sbcset == NULL || mbcset == NULL)
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
     {
       *err = REG_ESPACE;
       return NULL;
@@ -2943,7 +2942,7 @@ build_word_op (dfa, not, err)
     }
 
   ret = build_charclass (mbcset, sbcset, &alloc, "alpha");
-  if (ret != REG_NOERROR)
+  if (BE (ret != REG_NOERROR, 0))
     {
       re_free (sbcset);
       free_charset (mbcset);
@@ -2960,7 +2959,7 @@ build_word_op (dfa, not, err)
   br_token.opr.sbcset = sbcset;
   new_idx = re_dfa_add_node (dfa, br_token, 0);
   tree = create_tree (NULL, NULL, 0, new_idx);
-  if (new_idx == -1 || tree == NULL)
+  if (BE (new_idx == -1 || tree == NULL, 0))
     goto build_word_op_espace;
 
   if (MB_CUR_MAX > 1)
@@ -2973,13 +2972,13 @@ build_word_op (dfa, not, err)
       dfa->has_mb_node = 1;
       new_idx = re_dfa_add_node (dfa, br_token, 0);
       mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || mbc_tree == NULL)
+      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
         goto build_word_op_espace;
       /* Then join them by ALT node.  */
       alt_token.type = OP_ALT;
       new_idx = re_dfa_add_node (dfa, alt_token, 0);
       tree = create_tree (tree, mbc_tree, 0, new_idx);
-      if (new_idx != -1 && mbc_tree != NULL)
+      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
         return tree;
     }
   else
@@ -3013,11 +3012,11 @@ fetch_number (input, token, syntax)
       c = token->opr.c;
       if (token->type == OP_CLOSE_DUP_NUM || c == ',')
         break;
-      if (token->type != CHARACTER || c < '0' || '9' < c)
+      if (BE (token->type != CHARACTER || c < '0' || '9' < c, 0))
         return -2;
       num = (num == -1) ? c - '0' : num * 10 + c - '0';
     }
-  if (num > RE_DUP_MAX)
+  if (BE (num > RE_DUP_MAX, 0))
     return -2;
   return num;
 }
@@ -3050,7 +3049,7 @@ create_tree (left, right, type, index)
 {
   bin_tree_t *tree;
   tree = re_malloc (bin_tree_t, 1);
-  if (tree == NULL)
+  if (BE (tree == NULL, 0))
     {
       free_bin_tree (left);
       free_bin_tree (right);
@@ -3120,7 +3119,7 @@ duplicate_tree (src, dfa)
     {
       new_node_idx = re_dfa_add_node (dfa, dfa->nodes[src->node_idx], 0);
       dfa->nodes[new_node_idx].duplicated = 1;
-      if (new_node_idx == -1)
+      if (BE (new_node_idx == -1, 0))
         {
           free_bin_tree (left);
           free_bin_tree (right);
@@ -3131,7 +3130,7 @@ duplicate_tree (src, dfa)
     new_node_idx = src->type;
 
   new_tree = create_tree (left, right, src->type, new_node_idx);
-  if (new_tree == NULL)
+  if (BE (new_tree == NULL, 0))
     {
       free_bin_tree (left);
       free_bin_tree (right);
diff --git a/posix/regex.c b/posix/regex.c
index 0d5b51f013..03bda25f0b 100644
--- a/posix/regex.c
+++ b/posix/regex.c
@@ -41,6 +41,12 @@
 #  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
 #endif
 
+#if _LIBC || __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+#endif
+
 #include "regcomp.c"
 #include "regexec.c"
 #include "regex_internal.c"
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index 11726b340d..c2b0f9b4b0 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -96,7 +96,7 @@ re_string_construct (pstr, str, len, trans)
   if (MB_CUR_MAX >1 && pstr->len > 0)
     {
       ret = build_wcs_buffer (pstr);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
 #endif /* RE_ENABLE_I18N  */
@@ -104,7 +104,7 @@ re_string_construct (pstr, str, len, trans)
   if (trans != NULL)
     {
       ret = re_string_translate_buffer (pstr, trans);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -126,20 +126,20 @@ re_string_construct_toupper (pstr, str, len, trans)
 #ifdef RE_ENABLE_I18N
   if (MB_CUR_MAX >1)
     {
-      if (pstr->len > 0)
+      if (BE (pstr->len > 0, 1))
         {
           ret = build_wcs_upper_buffer (pstr);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             return ret;
         }
     }
   else
 #endif /* RE_ENABLE_I18N  */
     {
-      if (pstr->len > 0)
+      if (BE (pstr->len > 0, 1))
         {
           ret = build_upper_buffer (pstr);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             return ret;
         }
     }
@@ -147,7 +147,7 @@ re_string_construct_toupper (pstr, str, len, trans)
   if (trans != NULL)
     {
       ret = re_string_translate_buffer (pstr, trans);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -190,7 +190,7 @@ build_wcs_buffer (pstr)
   int char_idx, char_len, mbclen;
 
   pstr->wcs = re_malloc (wchar_t, pstr->len + 1);
-  if (pstr->wcs == NULL)
+  if (BE (pstr->wcs == NULL, 0))
     return REG_ESPACE;
 
   memset (&state, '\0', sizeof (mbstate_t));
@@ -200,7 +200,7 @@ build_wcs_buffer (pstr)
       int next_idx, remain_len = char_len - char_idx;
       prev_st = state;
       mbclen = mbrtowc (&wc, pstr->mbs + char_idx, remain_len, &state);
-      if (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0)
+      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
         /* We treat these cases as a singlebyte character.  */
         {
           mbclen = 1;
@@ -226,7 +226,7 @@ build_wcs_upper_buffer (pstr)
 
   pstr->wcs = re_malloc (wchar_t, pstr->len + 1);
   mbs_upper = re_malloc (unsigned char, pstr->len + 1);
-  if (pstr->wcs == NULL || mbs_upper == NULL)
+  if (BE (pstr->wcs == NULL || mbs_upper == NULL, 0))
     {
       pstr->wcs = NULL;
       return REG_ESPACE;
@@ -247,7 +247,8 @@ build_wcs_upper_buffer (pstr)
           else
             mbs_upper[char_idx] = pstr->mbs[char_idx];
         }
-      else if (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0)
+      else if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1
+                   || mbclen == 0, 0))
         /* We treat these cases as a singlebyte character.  */
         {
           mbclen = 1;
@@ -280,7 +281,7 @@ build_upper_buffer (pstr)
   int char_idx, char_len;
 
   mbs_upper = re_malloc (unsigned char, pstr->len + 1);
-  if (mbs_upper == NULL)
+  if (BE (mbs_upper == NULL, 0))
     return REG_ESPACE;
 
   char_len = pstr->len;
@@ -313,14 +314,14 @@ re_string_translate_buffer (pstr, trans)
     {
       transed_buf = (unsigned char *) pstr->mbs;
       transed_case_buf = re_malloc (unsigned char, pstr->len + 1);
-      if (transed_case_buf == NULL)
+      if (BE (transed_case_buf == NULL, 0))
         return REG_ESPACE;
       pstr->mbs_case_alloc = 1;
     }
   else
     {
       transed_buf = re_malloc (unsigned char, pstr->len + 1);
-      if (transed_buf == NULL)
+      if (BE (transed_buf == NULL, 0))
         return REG_ESPACE;
       transed_case_buf = NULL;
       pstr->mbs_alloc = 1;
@@ -381,7 +382,7 @@ re_string_context_at (input, idx, eflags, newline_anchor)
       unsigned int context = 0;
       if (idx < 0)
         context = CONTEXT_BEGBUF;
-      else if (idx == input->len)
+      else /* (idx == input->len) */
         context = CONTEXT_ENDBUF;
 
       if ((idx < 0 && !(eflags & REG_NOTBOL))
@@ -406,7 +407,7 @@ re_node_set_alloc (set, size)
   set->alloc = size;
   set->nelem = 0;
   set->elems = re_malloc (int, size);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   return REG_NOERROR;
 }
@@ -419,7 +420,7 @@ re_node_set_init_1 (set, elem)
   set->alloc = 1;
   set->nelem = 1;
   set->elems = re_malloc (int, 1);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   set->elems[0] = elem;
   return REG_NOERROR;
@@ -432,7 +433,7 @@ re_node_set_init_2 (set, elem1, elem2)
 {
   set->alloc = 2;
   set->elems = re_malloc (int, 2);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   if (elem1 == elem2)
     {
@@ -466,7 +467,7 @@ re_node_set_init_copy (dest, src)
     {
       dest->alloc = dest->nelem;
       dest->elems = re_malloc (int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
       memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
     }
@@ -491,7 +492,7 @@ re_node_set_intersect (dest, src1, src2)
         {
           dest->alloc = src1->nelem + src2->nelem;
           dest->elems = re_realloc (dest->elems, int, dest->alloc);
-          if (dest->elems == NULL)
+          if (BE (dest->elems == NULL, 0))
             return REG_ESPACE;
         }
     }
@@ -535,7 +536,7 @@ re_node_set_add_intersect (dest, src1, src2)
         {
           dest->alloc = src1->nelem + src2->nelem + dest->nelem;
           dest->elems = re_realloc (dest->elems, int, dest->alloc);
-          if (dest->elems == NULL)
+          if (BE (dest->elems == NULL, 0))
             return REG_ESPACE;
         }
     }
@@ -581,7 +582,7 @@ re_node_set_init_union (dest, src1, src2)
     {
       dest->alloc = src1->nelem + src2->nelem;
       dest->elems = re_malloc (int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -632,18 +633,11 @@ re_node_set_merge (dest, src)
   int si, di;
   if (src == NULL || src->nelem == 0)
     return REG_NOERROR;
-  else if (dest == NULL)
-    {
-      dest = re_malloc (re_node_set, 1);
-      if (dest == NULL)
-        return REG_ESPACE;
-      return re_node_set_init_copy (dest, src);
-    }
   if (dest->alloc < src->nelem + dest->nelem)
     {
       dest->alloc = 2 * (src->nelem + dest->alloc);
       dest->elems = re_realloc (dest->elems, int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
     }
 
@@ -709,7 +703,7 @@ re_node_set_insert (set, elem)
   /* In case of the set is empty.  */
   if (set->elems == NULL || set->alloc == 0)
     {
-      if (re_node_set_init_1 (set, elem) == REG_NOERROR)
+      if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
         return 1;
       else
         return -1;
@@ -733,7 +727,7 @@ re_node_set_insert (set, elem)
       int *new_array;
       set->alloc = set->alloc * 2;
       new_array = re_malloc (int, set->alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
         return -1;
       /* Copy the elements they are followed by the new element.  */
       if (idx > 0)
@@ -826,7 +820,7 @@ re_dfa_add_node (dfa, token, mode)
       re_token_t *new_array;
       dfa->nodes_alloc *= 2;
       new_array = re_realloc (dfa->nodes, re_token_t, dfa->nodes_alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
         return -1;
       else
         dfa->nodes = new_array;
@@ -842,8 +836,8 @@ re_dfa_add_node (dfa, token, mode)
                                       dfa->nodes_alloc);
           new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
                                          dfa->nodes_alloc);
-          if (new_firsts == NULL || new_nexts == NULL || new_edests == NULL
-              || new_eclosures == NULL || new_inveclosures == NULL)
+          if (BE (new_firsts == NULL || new_nexts == NULL || new_edests == NULL
+                  || new_eclosures == NULL || new_inveclosures == NULL, 0))
             return -1;
           dfa->firsts = new_firsts;
           dfa->nexts = new_nexts;
@@ -888,7 +882,7 @@ re_acquire_state (err, dfa, nodes)
   re_dfastate_t *new_state;
   struct re_state_table_entry *spot;
   int i;
-  if (nodes->nelem == 0)
+  if (BE (nodes->nelem == 0, 0))
     {
       *err = REG_NOERROR;
       return NULL;
@@ -896,26 +890,18 @@ re_acquire_state (err, dfa, nodes)
   hash = calc_state_hash (nodes, 0);
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
 
-  if (spot->alloc == 0)
+  for (i = 0 ; i < spot->num ; i++)
     {
-      /* Currently there are only one state in this spot.  */
-      if (spot->entry.state != NULL && hash == spot->entry.state->hash
-          && re_node_set_compare (&spot->entry.state->nodes, nodes))
-        return spot->entry.state;
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+        continue;
+      if (re_node_set_compare (&state->nodes, nodes))
+        return state;
     }
-  else
-    for (i = 0 ; i < spot->num ; i++)
-      {
-        re_dfastate_t *state = spot->entry.array[i];
-        if (hash != state->hash)
-          continue;
-        if (re_node_set_compare (&state->nodes, nodes))
-          return state;
-      }
 
   /* There are no appropriate state in the dfa, create the new one.  */
   new_state = create_ci_newstate (dfa, nodes, hash);
-  if (new_state != NULL)
+  if (BE (new_state != NULL, 1))
     return new_state;
   else
     {
@@ -953,27 +939,18 @@ re_acquire_state_context (err, dfa, nodes, context)
   hash = calc_state_hash (nodes, context);
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
 
-  if (spot->alloc == 0)
+  for (i = 0 ; i < spot->num ; i++)
     {
-      /* Currently there are only one state in this spot.  */
-      if (spot->entry.state != NULL && hash == spot->entry.state->hash
-          && re_node_set_compare (&spot->entry.state->nodes, nodes)
-          && spot->entry.state->context == context)
-        return spot->entry.state;
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+        continue;
+      if (re_node_set_compare (state->entrance_nodes, nodes)
+          && state->context == context)
+        return state;
     }
-  else
-    for (i = 0 ; i < spot->num ; i++)
-      {
-        re_dfastate_t *state = spot->entry.array[i];
-        if (hash != state->hash)
-          continue;
-        if (re_node_set_compare (state->entrance_nodes, nodes)
-            && state->context == context)
-          return state;
-      }
   /* There are no appropriate state in `dfa', create the new one.  */
   new_state = create_cd_newstate (dfa, nodes, context, hash);
-  if (new_state != NULL)
+  if (BE (new_state != NULL, 1))
     return new_state;
   else
     {
@@ -993,7 +970,7 @@ create_newstate_common (dfa, nodes, hash)
 {
   re_dfastate_t *newstate;
   newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   re_node_set_init_copy (&newstate->nodes, nodes);
   newstate->trtable = NULL;
@@ -1016,27 +993,12 @@ register_state (dfa, newstate, hash)
 
   if (spot->alloc <= spot->num)
     {
-      re_dfastate_t **new_array;
-
-      /* XXX Is spot->entry.array == NULL if spot->alloc == 0?  If yes
-	 the if can go away and only realloc is needed.  */
-      if (spot->alloc == 0)
-        {
-          spot->alloc = 4;
-          new_array = re_malloc (re_dfastate_t *, spot->alloc);
-	  if (new_array == NULL)
-            return REG_ESPACE;
-          new_array[0] = spot->entry.state;
-        }
-      else
-        {
-          spot->alloc = 2 * spot->num;
-          new_array = re_realloc (spot->entry.array, re_dfastate_t *,
-                                  spot->alloc);
-        }
-      spot->entry.array = new_array;
+      spot->alloc = 2 * spot->num + 2;
+      spot->array = re_realloc (spot->array, re_dfastate_t *, spot->alloc);
+      if (BE (spot->array == NULL, 0))
+        return REG_ESPACE;
     }
-  spot->entry.array[spot->num++] = newstate;
+  spot->array[spot->num++] = newstate;
   return REG_NOERROR;
 }
 
@@ -1053,7 +1015,7 @@ create_ci_newstate (dfa, nodes, hash)
   reg_errcode_t err;
   re_dfastate_t *newstate;
   newstate = create_newstate_common (dfa, nodes, hash);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   newstate->entrance_nodes = &newstate->nodes;
 
@@ -1098,7 +1060,7 @@ create_cd_newstate (dfa, nodes, context, hash)
   re_dfastate_t *newstate;
 
   newstate = create_newstate_common (dfa, nodes, hash);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   newstate->context = context;
   newstate->entrance_nodes = &newstate->nodes;
@@ -1139,7 +1101,7 @@ create_cd_newstate (dfa, nodes, context, hash)
           if (newstate->entrance_nodes == &newstate->nodes)
             {
               newstate->entrance_nodes = re_malloc (re_node_set, 1);
-	      if (newstate->entrance_nodes == NULL)
+	      if (BE (newstate->entrance_nodes == NULL, 0))
 		return NULL;
               re_node_set_init_copy (newstate->entrance_nodes, nodes);
               nctx_nodes = 0;
diff --git a/posix/regex_internal.h b/posix/regex_internal.h
index 38d68d47c0..f3ae7e1c64 100644
--- a/posix/regex_internal.h
+++ b/posix/regex_internal.h
@@ -360,11 +360,7 @@ struct re_state_table_entry
 {
   int num;
   int alloc;
-  union
-  {
-    re_dfastate_t *state;
-    re_dfastate_t **array;
-  } entry;
+  re_dfastate_t **array;
 };
 
 struct re_dfa_t
diff --git a/posix/regexec.c b/posix/regexec.c
index dc60e50e70..a069d7d3af 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -176,18 +176,20 @@ re_match (buffer, string, length, start, regs)
     struct re_registers *regs;
 {
   reg_errcode_t result;
-  int i, nregs, rval, eflags = 0;
+  int i, tmp_nregs, nregs, rval, eflags = 0;
   regmatch_t *pmatch;
 
   eflags |= (buffer->not_bol) ? REG_NOTBOL : 0;
   eflags |= (buffer->not_eol) ? REG_NOTEOL : 0;
 
   /* We need at least 1 register.  */
-  nregs = ((regs == NULL) ? 1
-           : ((regs->num_regs > buffer->re_nsub) ? buffer->re_nsub + 1
-              : regs->num_regs + 1));
+  tmp_nregs = ((buffer->no_sub || regs == NULL || regs->num_regs < 1) ? 1
+               : regs->num_regs);
+  nregs = ((tmp_nregs < buffer->re_nsub + 1
+            && buffer->regs_allocated == REGS_FIXED) ? tmp_nregs
+           : buffer->re_nsub + 1);
   pmatch = re_malloc (regmatch_t, nregs);
-  if (pmatch == NULL)
+  if (BE (pmatch == NULL, 0))
     return -2;
   result = re_search_internal (buffer, string, length, start, 0,
                                nregs, pmatch, eflags);
@@ -200,11 +202,10 @@ re_match (buffer, string, length, start, regs)
         { /* No.  So allocate them with malloc.  We need one
              extra element beyond `num_regs' for the `-1' marker
              GNU code uses.  */
-          regs->num_regs = ((RE_NREGS > buffer->re_nsub + 1) ? RE_NREGS
-                            : buffer->re_nsub + 1);
+          regs->num_regs = buffer->re_nsub + 1;
           regs->start = re_malloc (regoff_t, regs->num_regs);
           regs->end = re_malloc (regoff_t, regs->num_regs);
-          if (regs->start == NULL || regs->end == NULL)
+          if (BE (regs->start == NULL || regs->end == NULL, 0))
             {
               re_free (pmatch);
               return -2;
@@ -220,7 +221,7 @@ re_match (buffer, string, length, start, regs)
               regs->num_regs = buffer->re_nsub + 1;
               regs->start = re_realloc (regs->start, regoff_t, regs->num_regs);
               regs->end = re_realloc (regs->end, regoff_t, regs->num_regs);
-              if (regs->start == NULL || regs->end == NULL)
+              if (BE (regs->start == NULL || regs->end == NULL, 0))
                 {
                   re_free (pmatch);
                   return -2;
@@ -238,7 +239,9 @@ re_match (buffer, string, length, start, regs)
   /* Restore registers.  */
   if (regs != NULL)
     {
-      for (i = 0; i <= nregs; ++i)
+      int max_regs = ((regs->num_regs < buffer->re_nsub + 1) ? regs->num_regs
+                      : buffer->re_nsub + 1);
+      for (i = 0; i < max_regs; ++i)
         {
           regs->start[i] = pmatch[i].rm_so;
           regs->end[i] = pmatch[i].rm_eo;
@@ -279,7 +282,7 @@ re_match_2 (buffer, string1, length1, string2, length2, start, regs, stop)
 {
   int len, ret;
   char *str = re_malloc (char, length1 + length2);
-  if (str == NULL)
+  if (BE (str == NULL, 0))
     return -2;
   memcpy (str, string1, length1);
   memcpy (str + length1, string2, length2);
@@ -303,21 +306,25 @@ re_search (bufp, string, size, startpos, range, regs)
      struct re_registers *regs;
 {
   reg_errcode_t result;
-  int i, nregs, real_range, rval, eflags = 0;
+  int i, tmp_nregs, nregs, real_range, rval, eflags = 0;
   regmatch_t *pmatch;
 
   eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
   eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
 
   /* Check for out-of-range.  */
-  if (startpos < 0 || startpos > size)
+  if (BE (startpos < 0 || startpos > size, 0))
     return -1;
 
   /* We need at least 1 register.  */
-  nregs = ((regs == NULL) ? 1
-           : ((regs->num_regs > bufp->re_nsub) ? bufp->re_nsub + 1
-              : regs->num_regs + 1));
+  tmp_nregs = ((bufp->no_sub || regs == NULL || regs->num_regs < 1) ? 1
+               : regs->num_regs);
+  nregs = ((tmp_nregs < bufp->re_nsub + 1
+            && bufp->regs_allocated == REGS_FIXED) ? tmp_nregs
+           : bufp->re_nsub + 1);
   pmatch = re_malloc (regmatch_t, nregs);
+  if (BE (pmatch == NULL, 0))
+    return -2;
 
   /* Correct range if we need.  */
   real_range = ((startpos + range > size) ? size - startpos
@@ -338,11 +345,10 @@ re_search (bufp, string, size, startpos, range, regs)
         { /* No.  So allocate them with malloc.  We need one
              extra element beyond `num_regs' for the `-1' marker
              GNU code uses.  */
-          regs->num_regs = ((RE_NREGS > bufp->re_nsub + 1) ? RE_NREGS
-                            : bufp->re_nsub + 1);
+          regs->num_regs = bufp->re_nsub + 1;
           regs->start = re_malloc (regoff_t, regs->num_regs);
           regs->end = re_malloc (regoff_t, regs->num_regs);
-          if (regs->start == NULL || regs->end == NULL)
+          if (BE (regs->start == NULL || regs->end == NULL, 0))
             {
               re_free (pmatch);
               return -2;
@@ -358,7 +364,7 @@ re_search (bufp, string, size, startpos, range, regs)
               regs->num_regs = bufp->re_nsub + 1;
               regs->start = re_realloc (regs->start, regoff_t, regs->num_regs);
               regs->end = re_realloc (regs->end, regoff_t, regs->num_regs);
-              if (regs->start == NULL || regs->end == NULL)
+              if (BE (regs->start == NULL || regs->end == NULL, 0))
                 {
                   re_free (pmatch);
                   return -2;
@@ -376,7 +382,9 @@ re_search (bufp, string, size, startpos, range, regs)
   /* Restore registers.  */
   if (regs != NULL)
     {
-      for (i = 0; i <= bufp->re_nsub; ++i)
+      int max_regs = ((regs->num_regs < bufp->re_nsub + 1) ? regs->num_regs
+                      : bufp->re_nsub + 1);
+      for (i = 0; i < max_regs; ++i)
         {
           regs->start[i] = pmatch[i].rm_so;
           regs->end[i] = pmatch[i].rm_eo;
@@ -522,9 +530,9 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
                    ? preg->fastmap : NULL);
 
   /* Check if the DFA haven't been compiled.  */
-  if (preg->used == 0 || dfa->init_state == NULL
-      || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-      || dfa->init_state_begbuf == NULL)
+  if (BE (preg->used == 0 || dfa->init_state == NULL
+          || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+          || dfa->init_state_begbuf == NULL, 0))
     return REG_NOMATCH;
 
   re_node_set_init_empty (&empty_set);
@@ -539,7 +547,7 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
   if (nmatch > 1 || dfa->has_mb_node)
     {
       state_log = re_malloc (re_dfastate_t *, length + 1);
-      if (state_log == NULL)
+      if (BE (state_log == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -549,11 +557,11 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
     err = re_string_construct_toupper (&input, string, length, preg->translate);
   else
     err = re_string_construct (&input, string, length, preg->translate);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
 #ifdef DEBUG
@@ -581,7 +589,7 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
                                            match_first, 0, fl_longest_match);
               if (match_last != -1)
                 {
-                  if (match_last == -2)
+                  if (BE (match_last == -2, 0))
                     return REG_ESPACE;
                   else
                     break; /* We found a matching.  */
@@ -627,11 +635,11 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
           halt_node = check_halt_state_context (preg, pstate, &input,
                                                 match_last, eflags);
           err = sift_states_backward (preg, state_log, &mctx, &input, halt_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
           err = set_regs (preg, state_log, &mctx, &input, nmatch, pmatch,
                           halt_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
     }
@@ -707,7 +715,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
   cur_state = acquire_init_state_context (&err, preg, input, start_idx,
                                           mctx->eflags);
   /* An initial state must not be NULL(invalid state).  */
-  if (cur_state == NULL)
+  if (BE (cur_state == NULL, 0))
     return -2;
   if (state_log != NULL)
     state_log[start_idx] = cur_state;
@@ -735,7 +743,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
       if (cur_state == NULL) /* Reached at the invalid state or an error.  */
         {
           int cur_str_idx = re_string_cur_idx (input);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return -2;
           if (fl_search && !match)
             {
@@ -747,7 +755,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
                 cur_state = acquire_init_state_context (&err, preg, input,
                                                         cur_str_idx,
                                                         mctx->eflags);
-              if (cur_state == NULL && err != REG_NOERROR)
+              if (BE (cur_state == NULL && err != REG_NOERROR, 0))
                 return -2;
               if (state_log != NULL)
                 state_log[cur_str_idx] = cur_state;
@@ -853,7 +861,7 @@ proceed_next_node (preg, state_log, mctx, input, pidx, node, eps_via_nodes)
   if (IS_EPSILON_NODE (dfa->nodes[node].type))
     {
       err = re_node_set_insert (eps_via_nodes, node);
-      if (err < 0)
+      if (BE (err < 0, 0))
         return -1;
       for (i = 0; i < state_log[*pidx]->nodes.nelem; ++i)
         {
@@ -896,7 +904,7 @@ proceed_next_node (preg, state_log, mctx, input, pidx, node, eps_via_nodes)
           if (naccepted == 0)
             {
               err = re_node_set_insert (eps_via_nodes, node);
-              if (err < 0)
+              if (BE (err < 0, 0))
                 return -1;
               dest_node = dfa->nexts[node];
               if (re_node_set_contains (&state_log[*pidx]->nodes, dest_node))
@@ -996,7 +1004,7 @@ set_regs (preg, state_log, mctx, input, nmatch, pmatch, last_node)
       /* Proceed to next node.  */
       cur_node = proceed_next_node (preg, state_log, mctx, input, &idx,
                                     cur_node, &eps_via_nodes);
-      if (cur_node < 0)
+      if (BE (cur_node < 0, 0))
         return REG_ESPACE;
     }
   re_node_set_free (&eps_via_nodes);
@@ -1046,26 +1054,26 @@ sift_states_backward (preg, state_log, mctx, input, last_node)
   assert (state_log != NULL && state_log[str_idx] != NULL);
 #endif
   err = re_node_set_alloc (&state_buf, NUMBER_OF_STATE);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   plog = &state_log[str_idx]->nodes;
 
   /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
      transit to the last_node and the last_node itself.  */
   err = re_node_set_intersect (&state_buf, plog, dfa->inveclosures + last_node);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   if (state_log[str_idx] != NULL && state_log[str_idx]->has_backref)
     {
       err = add_epsilon_backreference (dfa, mctx, plog, str_idx, &state_buf);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
     }
 
   /* Update state log.  */
   state_log[str_idx] = re_acquire_state (&err, dfa, &state_buf);
-  if (state_log[str_idx] == NULL && err != REG_NOERROR)
+  if (BE (state_log[str_idx] == NULL && err != REG_NOERROR, 0))
     return err;
 
   /* Then check each states in the state_log.  */
@@ -1129,19 +1137,19 @@ sift_states_backward (preg, state_log, mctx, input, last_node)
              then we use plog->elems[i] instead.  */
           err = re_node_set_add_intersect (&state_buf, plog,
                                            dfa->inveclosures + prev_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
       if (state_log[str_idx] != NULL && state_log[str_idx]->has_backref)
         {
           err = add_epsilon_backreference (dfa, mctx, plog, str_idx, &state_buf);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
 
       /* Update state_log.  */
       state_log[str_idx] = re_acquire_state (&err, dfa, &state_buf);
-      if (state_log[str_idx] == NULL && err != REG_NOERROR)
+      if (BE (state_log[str_idx] == NULL && err != REG_NOERROR, 0))
         return err;
     }
 
@@ -1241,7 +1249,7 @@ add_epsilon_backreference (dfa, mctx, plog, idx, state_buf)
               reg_errcode_t err;
               err = re_node_set_add_intersect (state_buf, plog,
                                                dfa->inveclosures + node_idx);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return err;
               i = 0;
             }
@@ -1282,7 +1290,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
       if (state->accept_mb)
         {
           *err = transit_state_mb (preg, state, input, state_log, mctx);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
 
@@ -1307,7 +1315,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
           /* don't use transition table  */
           next_state = transit_state_sb (err, preg, state, input, fl_search,
                                          mctx);
-          if (next_state == NULL && err != REG_NOERROR)
+          if (BE (next_state == NULL && err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1341,7 +1349,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
               table_nodes = next_state->entrance_nodes;
               *err = re_node_set_init_union (&next_nodes, table_nodes,
                                              log_nodes);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 return NULL;
             }
           else
@@ -1363,7 +1371,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
       if (next_state != NULL && next_state->has_backref)
         {
           *err = transit_state_bkref (preg, next_state, input, state_log, mctx);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
           next_state = state_log[cur_idx];
         }
@@ -1392,7 +1400,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
   unsigned int context;
 
   *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
-  if (*err != REG_NOERROR)
+  if (BE (*err != REG_NOERROR, 0))
     return NULL;
   for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
     {
@@ -1402,7 +1410,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
         {
           *err = re_node_set_merge (&next_nodes,
                                     dfa->eclosures + dfa->nexts[cur_node]);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1422,7 +1430,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
         {
           *err = re_node_set_merge (&next_nodes,
                                     dfa->init_state->entrance_nodes);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1490,14 +1498,14 @@ transit_state_mb (preg, pstate, input, state_log, mctx)
         {
           err = re_node_set_init_union (&dest_nodes,
                                         dest_state->entrance_nodes, new_nodes);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
       context = re_string_context_at (input, dest_idx - 1, mctx->eflags,
                                       preg->newline_anchor);
       state_log[dest_idx] = re_acquire_state_context (&err, dfa, &dest_nodes,
                                                       context);
-      if (state_log[dest_idx] == NULL && err != REG_NOERROR)
+      if (BE (state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
         return err;
       if (dest_state != NULL)
         re_node_set_free (&dest_nodes);
@@ -1519,7 +1527,7 @@ transit_state_bkref (preg, pstate, input, state_log, mctx)
   assert (mctx->match_first != -1);
 #endif
   work_state_log = re_malloc (re_dfastate_t *, re_string_cur_idx (input) + 1);
-  if (work_state_log == NULL)
+  if (BE (work_state_log == NULL, 0))
     return REG_ESPACE;
 
   err = transit_state_bkref_loop (preg, input, &pstate->nodes, work_state_log,
@@ -1543,7 +1551,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
   int i, j;
   regmatch_t *cur_regs = re_malloc (regmatch_t, preg->re_nsub + 1);
   int cur_str_idx = re_string_cur_idx (input);
-  if (cur_regs == NULL)
+  if (BE (cur_regs == NULL, 0))
     return REG_ESPACE;
 
   for (i = 0; i < nodes->nelem; ++i)
@@ -1600,7 +1608,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
       /* Successfully matched, add a new cache entry.  */
       dest_str_idx = cur_str_idx + subexp_len;
       err = match_ctx_add_entry (mctx, node_idx, cur_str_idx, dest_str_idx);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
       clean_state_log_if_need (state_log, mctx, dest_str_idx);
 
@@ -1625,7 +1633,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
           state_log[dest_str_idx] = re_acquire_state_context (&err, dfa,
                                                               new_dest_nodes,
                                                               context);
-          if (state_log[dest_str_idx] == NULL && err != REG_NOERROR)
+          if (BE (state_log[dest_str_idx] == NULL && err != REG_NOERROR, 0))
             return err;
         }
       else
@@ -1633,12 +1641,12 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
           re_node_set dest_nodes;
           err = re_node_set_init_union (&dest_nodes, dest_state->entrance_nodes,
                                         new_dest_nodes);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
           state_log[dest_str_idx] = re_acquire_state_context (&err, dfa,
                                                               &dest_nodes,
                                                               context);
-          if (state_log[dest_str_idx] == NULL && err != REG_NOERROR)
+          if (BE (state_log[dest_str_idx] == NULL && err != REG_NOERROR, 0))
             return err;
           re_node_set_free (&dest_nodes);
         }
@@ -1649,7 +1657,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
         {
           err = transit_state_bkref_loop (preg, input, new_dest_nodes,
                                           work_state_log, state_log, mctx);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
     }
@@ -1684,13 +1692,13 @@ build_trtable (preg, state, fl_search)
 
   /* Initialize transiton table.  */
   trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
-  if (dests_node == NULL || dests_ch == NULL || trtable == NULL)
+  if (BE (dests_node == NULL || dests_ch == NULL || trtable == NULL, 0))
     return NULL;
 
   /* At first, group all nodes belonging to `state' into several
      destinations.  */
   ndests = group_nodes_into_DFAstates (preg, state, dests_node, dests_ch);
-  if (ndests <= 0)
+  if (BE (ndests <= 0, 0))
     {
       re_free (dests_node);
       re_free (dests_ch);
@@ -1704,8 +1712,8 @@ build_trtable (preg, state, fl_search)
   bitset_empty (acceptable);
 
   err = re_node_set_alloc (&follows, ndests + 1);
-  if (dest_states == NULL || dest_states_word == NULL || dest_states_nl == NULL
-      || err != REG_NOERROR)
+  if (BE (dest_states == NULL || dest_states_word == NULL
+          || dest_states_nl == NULL || err != REG_NOERROR, 0))
     return NULL;
 
   /* Then build the states for all destinations.  */
@@ -1720,7 +1728,7 @@ build_trtable (preg, state, fl_search)
           if (next_node != -1)
             {
               err = re_node_set_merge (&follows, dfa->eclosures + next_node);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return NULL;
             }
         }
@@ -1740,12 +1748,12 @@ build_trtable (preg, state, fl_search)
             {
               err = re_node_set_merge (&follows,
                                        dfa->init_state->entrance_nodes);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return NULL;
             }
         }
       dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
-      if (dest_states[i] == NULL && err != REG_NOERROR)
+      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
         return NULL;
       /* If the new state has context constraint,
          build appropriate states for these contexts.  */
@@ -1753,11 +1761,11 @@ build_trtable (preg, state, fl_search)
         {
           dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
                                                           CONTEXT_WORD);
-          if (dest_states_word[i] == NULL && err != REG_NOERROR)
+          if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
             return NULL;
           dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
                                                         CONTEXT_NEWLINE);
-          if (dest_states_nl[i] == NULL && err != REG_NOERROR)
+          if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
             return NULL;
         }
       else
@@ -1915,14 +1923,14 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
               bitset_copy (dests_ch[ndests], remains);
               bitset_copy (dests_ch[j], intersec);
               err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return -1;
               ++ndests;
             }
 
           /* Put the position in the current group. */
           err = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-          if (err < 0)
+          if (BE (err < 0, 0))
             return -1;
 
           /* If all characters are consumed, go to next node. */
@@ -1934,7 +1942,7 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
         {
           bitset_copy (dests_ch[ndests], accepts);
           err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return -1;
           ++ndests;
           bitset_empty (accepts);
@@ -2209,7 +2217,7 @@ match_ctx_init (mctx, eflags, n)
   if (n > 0)
     {
       mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
-      if (mctx->bkref_ents == NULL)
+      if (BE (mctx->bkref_ents == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -2239,7 +2247,7 @@ match_ctx_add_entry (mctx, node, from, to)
       mctx->bkref_ents = re_realloc (mctx->bkref_ents,
                                      struct re_backref_cache_entry,
                                      mctx->abkref_ents * 2);
-      if (mctx->bkref_ents == NULL)
+      if (BE (mctx->bkref_ents == NULL, 0))
         return REG_ESPACE;
       memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
              sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
diff --git a/sysdeps/i386/i586/strlen.S b/sysdeps/i386/i586/strlen.S
index 46478f7541..34151305cf 100644
--- a/sysdeps/i386/i586/strlen.S
+++ b/sysdeps/i386/i586/strlen.S
@@ -1,6 +1,6 @@
-/* strlen -- Compute length og NUL terminated string.
+/* strlen -- Compute length of NUL terminated string.
    Highly optimized version for ix86, x>=5.
-   Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
 
diff --git a/sysdeps/i386/i686/strcmp.S b/sysdeps/i386/i686/strcmp.S
index fcc1b7c400..760d9d8a99 100644
--- a/sysdeps/i386/i686/strcmp.S
+++ b/sysdeps/i386/i686/strcmp.S
@@ -1,5 +1,5 @@
 /* Highly optimized version for ix86, x>=6.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
 
@@ -49,7 +49,8 @@ L(oop):	movb	(%ecx), %al
 	   the end of the NUL terminators.  */
 	CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jbe)
 	CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jbe)
-	jmp	L(out)
+	LEAVE
+	ret
 
 #ifndef __BOUNDED_POINTERS__
 L(neq):	movl	$1, %eax
@@ -65,6 +66,6 @@ L(chk):	CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jb)
 	CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jb)
 #endif
 
-L(out):	LEAVE
+	LEAVE
 	ret
 END (BP_SYM (strcmp))