gas: xtensa: limit size of auto litpools

Message ID 1518394719-6457-1-git-send-email-jcmvbkbc@gmail.com
State New
Headers show
Series
  • gas: xtensa: limit size of auto litpools
Related show

Commit Message

Max Filippov Feb. 12, 2018, 12:18 a.m.
Literal movement code may grow auto litpool so big that it won't be
possible to jump around it. Limit the size of auto litpools by 1/2 of
the jump range.

gas/
2018-02-08  Max Filippov  <jcmvbkbc@gmail.com>

	* config/tc-xtensa.c (struct litpool_frag): Add new field
	literal_count.
	(MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)
	(MAX_POOL_LITERALS): New macro definitions.
	(auto_litpool_limit): Initialize to 0.
	(md_parse_option): Set auto_litpool_limit in the presence of
	--auto-litpools option.
	(xtensa_maybe_create_literal_pool_frag): Zero-initialize
	literal_count field.
	(xg_find_litpool): New function. Make sure that found literal
	pool size is within the limit.
	(xtensa_move_literals): Extract literal pool search code into
	the new function.
	* testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.
	* testsuite/gas/xtensa/auto-litpools-2.d: New file.
	* testsuite/gas/xtensa/auto-litpools-2.s: New file.
	* testsuite/gas/xtensa/auto-litpools.d: Fix up changed
	addresses.
	* testsuite/gas/xtensa/auto-litpools.s: Change literal value so
	that objdump doesn't get out of sync.
---
 gas/config/tc-xtensa.c                     | 119 +++++++++++++++++++----------
 gas/testsuite/gas/xtensa/all.exp           |   1 +
 gas/testsuite/gas/xtensa/auto-litpools-2.d |   6 ++
 gas/testsuite/gas/xtensa/auto-litpools-2.s |   9 +++
 gas/testsuite/gas/xtensa/auto-litpools.d   |   4 +-
 gas/testsuite/gas/xtensa/auto-litpools.s   |   2 +-
 6 files changed, 96 insertions(+), 45 deletions(-)
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.d
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.s

-- 
2.1.4

Comments

Max Filippov Feb. 20, 2018, 7:15 p.m. | #1
On Sun, Feb 11, 2018 at 4:18 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> Literal movement code may grow auto litpool so big that it won't be

> possible to jump around it. Limit the size of auto litpools by 1/2 of

> the jump range.


Ping?

> gas/

> 2018-02-08  Max Filippov  <jcmvbkbc@gmail.com>

>

>         * config/tc-xtensa.c (struct litpool_frag): Add new field

>         literal_count.

>         (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)

>         (MAX_POOL_LITERALS): New macro definitions.

>         (auto_litpool_limit): Initialize to 0.

>         (md_parse_option): Set auto_litpool_limit in the presence of

>         --auto-litpools option.

>         (xtensa_maybe_create_literal_pool_frag): Zero-initialize

>         literal_count field.

>         (xg_find_litpool): New function. Make sure that found literal

>         pool size is within the limit.

>         (xtensa_move_literals): Extract literal pool search code into

>         the new function.

>         * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.

>         * testsuite/gas/xtensa/auto-litpools-2.d: New file.

>         * testsuite/gas/xtensa/auto-litpools-2.s: New file.

>         * testsuite/gas/xtensa/auto-litpools.d: Fix up changed

>         addresses.

>         * testsuite/gas/xtensa/auto-litpools.s: Change literal value so

>         that objdump doesn't get out of sync.

> ---

>  gas/config/tc-xtensa.c                     | 119 +++++++++++++++++++----------

>  gas/testsuite/gas/xtensa/all.exp           |   1 +

>  gas/testsuite/gas/xtensa/auto-litpools-2.d |   6 ++

>  gas/testsuite/gas/xtensa/auto-litpools-2.s |   9 +++

>  gas/testsuite/gas/xtensa/auto-litpools.d   |   4 +-

>  gas/testsuite/gas/xtensa/auto-litpools.s   |   2 +-

>  6 files changed, 96 insertions(+), 45 deletions(-)

>  create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.d

>  create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.s

>

> diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c

> index 1dbb73aa55c7..74a55019bdd9 100644

> --- a/gas/config/tc-xtensa.c

> +++ b/gas/config/tc-xtensa.c

> @@ -438,6 +438,7 @@ struct litpool_frag

>    addressT addr;

>    short priority; /* 1, 2, or 3 -- 1 is highest  */

>    short original_priority;

> +  int literal_count;

>  };

>

>  /* Map a segment to its litpool_frag list.  */

> @@ -451,6 +452,14 @@ struct litpool_seg

>

>  static struct litpool_seg litpool_seg_list;

>

> +/* Limit maximal size of auto litpool by half of the j range.  */

> +#define MAX_AUTO_POOL_LITERALS 16384

> +

> +/* Limit maximal size of explicit literal pool by l32r range.  */

> +#define MAX_EXPLICIT_POOL_LITERALS 65536

> +

> +#define MAX_POOL_LITERALS \

> +  (auto_litpools ? MAX_AUTO_POOL_LITERALS : MAX_EXPLICIT_POOL_LITERALS)

>

>  /* Directive functions.  */

>

> @@ -488,7 +497,7 @@ static int init_trampoline_frag (fragS *);

>  static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);

>  static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);

>  static bfd_boolean auto_litpools = FALSE;

> -static int auto_litpool_limit = 10000;

> +static int auto_litpool_limit = 0;

>

>  /* Alignment Functions.  */

>

> @@ -984,6 +993,8 @@ md_parse_option (int c, const char *arg)

>      case option_auto_litpools:

>        auto_litpools = TRUE;

>        use_literal_section = FALSE;

> +      if (auto_litpool_limit <= 0)

> +       auto_litpool_limit = MAX_AUTO_POOL_LITERALS / 2;

>        return 1;

>

>      case option_no_auto_litpools:

> @@ -7912,6 +7923,7 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create,

>    lpf->fragP = fragP;

>    lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;

>    lpf->original_priority = lpf->priority;

> +  lpf->literal_count = 0;

>

>    lps->frag_count = 0;

>  }

> @@ -11187,6 +11199,66 @@ xg_promote_candidate_litpool (struct litpool_seg *lps,

>    /* Rest is done in xtensa_relax_frag.  */

>  }

>

> +static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps,

> +                                            struct litpool_frag *lpf,

> +                                            addressT addr)

> +{

> +  struct litpool_frag *lp = lpf->prev;

> +

> +  gas_assert (lp->fragP);

> +

> +  while (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)

> +    {

> +      lp = lp->prev;

> +      if (lp->fragP == NULL)

> +       {

> +         /* End of list; have to bite the bullet.

> +            Take the nearest.  */

> +         lp = lpf->prev;

> +         break;

> +       }

> +      /* Does it (conservatively) reach?  */

> +      if (addr - lp->addr <= 128 * 1024)

> +       {

> +         if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&

> +             lp->literal_count < MAX_POOL_LITERALS)

> +           {

> +             /* Found a good one.  */

> +             break;

> +           }

> +         else if (lp->prev->fragP &&

> +                  addr - lp->prev->addr > 128 * 1024 &&

> +                  lp->prev->literal_count < MAX_POOL_LITERALS)

> +           {

> +             /* This is still a "candidate" but the next one

> +                will be too far away, so revert to the nearest

> +                one, convert it and add the jump around.  */

> +             lp = lpf->prev;

> +             break;

> +           }

> +       }

> +    }

> +

> +  if (lp->literal_count >= MAX_POOL_LITERALS)

> +    {

> +      lp = lpf->prev;

> +      while (lp && lp->fragP && lp->literal_count >= MAX_POOL_LITERALS)

> +       {

> +         lp = lp->prev;

> +       }

> +      gas_assert (lp);

> +    }

> +

> +  gas_assert (lp && lp->fragP && lp->literal_count < MAX_POOL_LITERALS);

> +  ++lp->literal_count;

> +

> +  /* Convert candidate and add the jump around.  */

> +  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)

> +    xg_promote_candidate_litpool (lps, lp);

> +

> +  return lp;

> +}

> +

>  static void

>  xtensa_move_literals (void)

>  {

> @@ -11244,49 +11316,12 @@ xtensa_move_literals (void)

>                              preferring non-"candidate" positions to avoid

>                              the jump-around.  */

>                           fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];

> -                         struct litpool_frag *lp = lpf->prev;

> -                         if (!lp->fragP)

> -                           {

> -                             break;

> -                           }

> -                         while (lp->fragP->fr_subtype ==

> -                                RELAX_LITERAL_POOL_CANDIDATE_BEGIN)

> -                           {

> -                             lp = lp->prev;

> -                             if (lp->fragP == NULL)

> -                               {

> -                                 /* End of list; have to bite the bullet.

> -                                    Take the nearest.  */

> -                                 lp = lpf->prev;

> -                                 break;

> -                               }

> -                             /* Does it (conservatively) reach?  */

> -                             if (addr - lp->addr <= 128 * 1024)

> -                               {

> -                                 if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)

> -                                   {

> -                                     /* Found a good one.  */

> -                                     break;

> -                                   }

> -                                 else if (lp->prev->fragP &&

> -                                          addr - lp->prev->addr > 128 * 1024)

> -                                   {

> -                                     /* This is still a "candidate" but the next one

> -                                        will be too far away, so revert to the nearest

> -                                        one, convert it and add the jump around.  */

> -                                     lp = lpf->prev;

> -                                     break;

> -                                   }

> -                               }

> -                           }

>

> -                         /* Convert candidate and add the jump around.  */

> -                         if (lp->fragP->fr_subtype ==

> -                             RELAX_LITERAL_POOL_CANDIDATE_BEGIN)

> -                           xg_promote_candidate_litpool (lps, lp);

> -

> -                         if (! litfrag->tc_frag_data.literal_frag)

> +                         if (!litfrag->tc_frag_data.literal_frag)

>                             {

> +                             struct litpool_frag *lp;

> +

> +                             lp = xg_find_litpool (lps, lpf, addr);

>                               /* Take earliest use of this literal to avoid

>                                  forward refs.  */

>                               litfrag->tc_frag_data.literal_frag = lp->fragP;

> diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp

> index c0dd8a5fa025..650a93223d46 100644

> --- a/gas/testsuite/gas/xtensa/all.exp

> +++ b/gas/testsuite/gas/xtensa/all.exp

> @@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then {

>      run_list_test "trampoline-2"

>      run_dump_test "first_frag_align"

>      run_dump_test "auto-litpools"

> +    run_dump_test "auto-litpools-2"

>      run_dump_test "auto-litpools-first1"

>      run_dump_test "auto-litpools-first2"

>      run_dump_test "loc"

> diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.d b/gas/testsuite/gas/xtensa/auto-litpools-2.d

> new file mode 100644

> index 000000000000..d153c2bdac95

> --- /dev/null

> +++ b/gas/testsuite/gas/xtensa/auto-litpools-2.d

> @@ -0,0 +1,6 @@

> +#as: --auto-litpools

> +#objdump: -d

> +#name: auto litpool size limitation

> +

> +.*: +file format .*xtensa.*

> +#...

> diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.s b/gas/testsuite/gas/xtensa/auto-litpools-2.s

> new file mode 100644

> index 000000000000..30b1383d009c

> --- /dev/null

> +++ b/gas/testsuite/gas/xtensa/auto-litpools-2.s

> @@ -0,0 +1,9 @@

> +       .text

> +       .global _start

> +_start:

> +       j       1f

> +       .rep    33000

> +       movi    a2, 0xf03df03d

> +       .endr

> +1:

> +       ret

> diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d

> index fc6f5cbbc308..8eadd1f08cf6 100644

> --- a/gas/testsuite/gas/xtensa/auto-litpools.d

> +++ b/gas/testsuite/gas/xtensa/auto-litpools.d

> @@ -6,7 +6,7 @@

>  #...

>  .*8:.*l32r.a2, 4 .*

>  #...

> -.*3e43b:.*j.3e444 .*

> +.*3f029:.*j.3f030 .*

>  #...

> -.*40754:.*l32r.a2, 3e440 .*

> +.*40752:.*l32r.a2, 3f02c .*

>  #...

> diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s

> index 9a5b26ba16c9..aa4241533027 100644

> --- a/gas/testsuite/gas/xtensa/auto-litpools.s

> +++ b/gas/testsuite/gas/xtensa/auto-litpools.s

> @@ -1,7 +1,7 @@

>         .text

>         .align  4

>         .literal        .L0, 0x12345

> -       .literal        .L1, 0x12345

> +       .literal        .L1, 0x78f078f0

>

>  f:

>         l32r    a2, .L0

> --

> 2.1.4

>




-- 
Thanks.
-- Max
augustine.sterling@gmail.com Feb. 20, 2018, 7:19 p.m. | #2
On Sun, Feb 11, 2018 at 4:18 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> Literal movement code may grow auto litpool so big that it won't be

> possible to jump around it. Limit the size of auto litpools by 1/2 of

> the jump range.

>

> gas/

> 2018-02-08  Max Filippov  <jcmvbkbc@gmail.com>

>

>         * config/tc-xtensa.c (struct litpool_frag): Add new field

>         literal_count.

>         (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)

>         (MAX_POOL_LITERALS): New macro definitions.

>         (auto_litpool_limit): Initialize to 0.

>         (md_parse_option): Set auto_litpool_limit in the presence of

>         --auto-litpools option.

>         (xtensa_maybe_create_literal_pool_frag): Zero-initialize

>         literal_count field.

>         (xg_find_litpool): New function. Make sure that found literal

>         pool size is within the limit.

>         (xtensa_move_literals): Extract literal pool search code into

>         the new function.

>         * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.

>         * testsuite/gas/xtensa/auto-litpools-2.d: New file.

>         * testsuite/gas/xtensa/auto-litpools-2.s: New file.

>         * testsuite/gas/xtensa/auto-litpools.d: Fix up changed

>         addresses.

>         * testsuite/gas/xtensa/auto-litpools.s: Change literal value so

>         that objdump doesn't get out of sync.



This is OK for binutils.
Max Filippov Feb. 20, 2018, 7:55 p.m. | #3
On Tue, Feb 20, 2018 at 11:19 AM, augustine.sterling@gmail.com
<augustine.sterling@gmail.com> wrote:
> On Sun, Feb 11, 2018 at 4:18 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:

>> Literal movement code may grow auto litpool so big that it won't be

>> possible to jump around it. Limit the size of auto litpools by 1/2 of

>> the jump range.

>>

>> gas/

>> 2018-02-08  Max Filippov  <jcmvbkbc@gmail.com>

>>

>>         * config/tc-xtensa.c (struct litpool_frag): Add new field

>>         literal_count.

>>         (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)

>>         (MAX_POOL_LITERALS): New macro definitions.

>>         (auto_litpool_limit): Initialize to 0.

>>         (md_parse_option): Set auto_litpool_limit in the presence of

>>         --auto-litpools option.

>>         (xtensa_maybe_create_literal_pool_frag): Zero-initialize

>>         literal_count field.

>>         (xg_find_litpool): New function. Make sure that found literal

>>         pool size is within the limit.

>>         (xtensa_move_literals): Extract literal pool search code into

>>         the new function.

>>         * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.

>>         * testsuite/gas/xtensa/auto-litpools-2.d: New file.

>>         * testsuite/gas/xtensa/auto-litpools-2.s: New file.

>>         * testsuite/gas/xtensa/auto-litpools.d: Fix up changed

>>         addresses.

>>         * testsuite/gas/xtensa/auto-litpools.s: Change literal value so

>>         that objdump doesn't get out of sync.

>

>

> This is OK for binutils.


Thanks, applied to master.

-- Max

Patch

diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 1dbb73aa55c7..74a55019bdd9 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -438,6 +438,7 @@  struct litpool_frag
   addressT addr;
   short priority; /* 1, 2, or 3 -- 1 is highest  */
   short original_priority;
+  int literal_count;
 };
 
 /* Map a segment to its litpool_frag list.  */
@@ -451,6 +452,14 @@  struct litpool_seg
 
 static struct litpool_seg litpool_seg_list;
 
+/* Limit maximal size of auto litpool by half of the j range.  */
+#define MAX_AUTO_POOL_LITERALS 16384
+
+/* Limit maximal size of explicit literal pool by l32r range.  */
+#define MAX_EXPLICIT_POOL_LITERALS 65536
+
+#define MAX_POOL_LITERALS \
+  (auto_litpools ? MAX_AUTO_POOL_LITERALS : MAX_EXPLICIT_POOL_LITERALS)
 
 /* Directive functions.  */
 
@@ -488,7 +497,7 @@  static int init_trampoline_frag (fragS *);
 static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);
 static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
 static bfd_boolean auto_litpools = FALSE;
-static int auto_litpool_limit = 10000;
+static int auto_litpool_limit = 0;
 
 /* Alignment Functions.  */
 
@@ -984,6 +993,8 @@  md_parse_option (int c, const char *arg)
     case option_auto_litpools:
       auto_litpools = TRUE;
       use_literal_section = FALSE;
+      if (auto_litpool_limit <= 0)
+	auto_litpool_limit = MAX_AUTO_POOL_LITERALS / 2;
       return 1;
 
     case option_no_auto_litpools:
@@ -7912,6 +7923,7 @@  xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
   lpf->fragP = fragP;
   lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
   lpf->original_priority = lpf->priority;
+  lpf->literal_count = 0;
 
   lps->frag_count = 0;
 }
@@ -11187,6 +11199,66 @@  xg_promote_candidate_litpool (struct litpool_seg *lps,
   /* Rest is done in xtensa_relax_frag.  */
 }
 
+static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps,
+					     struct litpool_frag *lpf,
+					     addressT addr)
+{
+  struct litpool_frag *lp = lpf->prev;
+
+  gas_assert (lp->fragP);
+
+  while (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+    {
+      lp = lp->prev;
+      if (lp->fragP == NULL)
+	{
+	  /* End of list; have to bite the bullet.
+	     Take the nearest.  */
+	  lp = lpf->prev;
+	  break;
+	}
+      /* Does it (conservatively) reach?  */
+      if (addr - lp->addr <= 128 * 1024)
+	{
+	  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
+	      lp->literal_count < MAX_POOL_LITERALS)
+	    {
+	      /* Found a good one.  */
+	      break;
+	    }
+	  else if (lp->prev->fragP &&
+		   addr - lp->prev->addr > 128 * 1024 &&
+		   lp->prev->literal_count < MAX_POOL_LITERALS)
+	    {
+	      /* This is still a "candidate" but the next one
+		 will be too far away, so revert to the nearest
+		 one, convert it and add the jump around.  */
+	      lp = lpf->prev;
+	      break;
+	    }
+	}
+    }
+
+  if (lp->literal_count >= MAX_POOL_LITERALS)
+    {
+      lp = lpf->prev;
+      while (lp && lp->fragP && lp->literal_count >= MAX_POOL_LITERALS)
+	{
+	  lp = lp->prev;
+	}
+      gas_assert (lp);
+    }
+
+  gas_assert (lp && lp->fragP && lp->literal_count < MAX_POOL_LITERALS);
+  ++lp->literal_count;
+
+  /* Convert candidate and add the jump around.  */
+  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+    xg_promote_candidate_litpool (lps, lp);
+
+  return lp;
+}
+
 static void
 xtensa_move_literals (void)
 {
@@ -11244,49 +11316,12 @@  xtensa_move_literals (void)
 			     preferring non-"candidate" positions to avoid
 			     the jump-around.  */
 			  fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
-			  struct litpool_frag *lp = lpf->prev;
-			  if (!lp->fragP)
-			    {
-			      break;
-			    }
-			  while (lp->fragP->fr_subtype ==
-				 RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
-			    {
-			      lp = lp->prev;
-			      if (lp->fragP == NULL)
-				{
-				  /* End of list; have to bite the bullet.
-				     Take the nearest.  */
-				  lp = lpf->prev;
-				  break;
-				}
-			      /* Does it (conservatively) reach?  */
-			      if (addr - lp->addr <= 128 * 1024)
-				{
-				  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
-				    {
-				      /* Found a good one.  */
-				      break;
-				    }
-				  else if (lp->prev->fragP &&
-					   addr - lp->prev->addr > 128 * 1024)
-				    {
-				      /* This is still a "candidate" but the next one
-				         will be too far away, so revert to the nearest
-					 one, convert it and add the jump around.  */
-				      lp = lpf->prev;
-				      break;
-				    }
-				}
-			    }
 
-			  /* Convert candidate and add the jump around.  */
-			  if (lp->fragP->fr_subtype ==
-			      RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
-			    xg_promote_candidate_litpool (lps, lp);
-
-			  if (! litfrag->tc_frag_data.literal_frag)
+			  if (!litfrag->tc_frag_data.literal_frag)
 			    {
+			      struct litpool_frag *lp;
+
+			      lp = xg_find_litpool (lps, lpf, addr);
 			      /* Take earliest use of this literal to avoid
 				 forward refs.  */
 			      litfrag->tc_frag_data.literal_frag = lp->fragP;
diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
index c0dd8a5fa025..650a93223d46 100644
--- a/gas/testsuite/gas/xtensa/all.exp
+++ b/gas/testsuite/gas/xtensa/all.exp
@@ -102,6 +102,7 @@  if [istarget xtensa*-*-*] then {
     run_list_test "trampoline-2"
     run_dump_test "first_frag_align"
     run_dump_test "auto-litpools"
+    run_dump_test "auto-litpools-2"
     run_dump_test "auto-litpools-first1"
     run_dump_test "auto-litpools-first2"
     run_dump_test "loc"
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.d b/gas/testsuite/gas/xtensa/auto-litpools-2.d
new file mode 100644
index 000000000000..d153c2bdac95
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-2.d
@@ -0,0 +1,6 @@ 
+#as: --auto-litpools
+#objdump: -d
+#name: auto litpool size limitation
+
+.*: +file format .*xtensa.*
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.s b/gas/testsuite/gas/xtensa/auto-litpools-2.s
new file mode 100644
index 000000000000..30b1383d009c
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-2.s
@@ -0,0 +1,9 @@ 
+	.text
+	.global _start
+_start:
+	j	1f
+	.rep	33000
+	movi	a2, 0xf03df03d
+	.endr
+1:
+	ret
diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
index fc6f5cbbc308..8eadd1f08cf6 100644
--- a/gas/testsuite/gas/xtensa/auto-litpools.d
+++ b/gas/testsuite/gas/xtensa/auto-litpools.d
@@ -6,7 +6,7 @@ 
 #...
 .*8:.*l32r.a2, 4 .*
 #...
-.*3e43b:.*j.3e444 .*
+.*3f029:.*j.3f030 .*
 #...
-.*40754:.*l32r.a2, 3e440 .*
+.*40752:.*l32r.a2, 3f02c .*
 #...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s
index 9a5b26ba16c9..aa4241533027 100644
--- a/gas/testsuite/gas/xtensa/auto-litpools.s
+++ b/gas/testsuite/gas/xtensa/auto-litpools.s
@@ -1,7 +1,7 @@ 
 	.text
 	.align	4
 	.literal	.L0, 0x12345
-	.literal	.L1, 0x12345
+	.literal	.L1, 0x78f078f0
 
 f:
 	l32r	a2, .L0