PATCH: PR target/54445: TLS array lookup with negative constant is not combined into a single instruction

H.J. Lu hjl.tools@gmail.com
Wed Sep 12 17:18:00 GMT 2012


On Sun, Sep 2, 2012 at 7:20 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> Hi,
>
> When x86-64 TLS support was added by:
>
> http://gcc.gnu.org/ml/gcc-patches/2002-10/msg01262.html
>
> it didn't allow negative offset.  Jakub, do you remember the reason for
> it?  I tested this patch on Linux/x86-64 and used the new GCC to build
> glibc for x86-64 and x32.  There are no regressions.  OK to install?
>
> Thanks.
>
>
> H.J.
> ----
> gcc/
>
> 2012-09-02  H.J. Lu  <hongjiu.lu@intel.com>
>
>         PR target/54445
>         * config/i386/predicates.md (x86_64_immediate_operand): Allow
>         negative offset for UNSPEC_DTPOFF/UNSPEC_NTPOFF.
>
> gcc/testsuite/
> 2012-09-02  H.J. Lu  <hongjiu.lu@intel.com>
>
>         PR target/54445
>         * gcc.target/i386/pr54445-1.c: New file.
>         * gcc.target/i386/pr54445-2.c: Likewise.
>
> diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
> index 55e4b56..159594e 100644
> --- a/gcc/config/i386/predicates.md
> +++ b/gcc/config/i386/predicates.md
> @@ -228,8 +228,7 @@
>                 {
>                 case UNSPEC_DTPOFF:
>                 case UNSPEC_NTPOFF:
> -                 if (offset > 0
> -                     && trunc_int_for_mode (offset, SImode) == offset)
> +                 if (trunc_int_for_mode (offset, SImode) == offset)
>                     return true;
>                 }
>               break;
> diff --git a/gcc/testsuite/gcc.target/i386/pr54445-1.c b/gcc/testsuite/gcc.target/i386/pr54445-1.c
> new file mode 100644
> index 0000000..72ef84e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr54445-1.c
> @@ -0,0 +1,24 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +__thread unsigned char tls_array[64];
> +
> +unsigned char
> +__attribute__ ((noinline))
> +tls_array_lookup_with_negative_constant(long long int position) {
> +  return tls_array[position - 1];
> +}
> +
> +int
> +main ()
> +{
> +  int i;
> +
> +  for (i = 0; i < sizeof (tls_array) / sizeof (tls_array[0]); i++)
> +    tls_array[i] = i;
> +
> +  for (i = 0; i < sizeof (tls_array) / sizeof (tls_array[0]); i++)
> +    if (i != tls_array_lookup_with_negative_constant (i + 1))
> +      __builtin_abort ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr54445-2.c b/gcc/testsuite/gcc.target/i386/pr54445-2.c
> new file mode 100644
> index 0000000..5151c13
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr54445-2.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile { target { *-*-linux* && { ! { ia32 } } } } } */
> +/* { dg-options "-O2 -fno-pic" } */
> +
> +__thread unsigned char tls_array[64];
> +
> +unsigned char
> +tls_array_lookup_with_negative_constant(long long int position) {
> +  return tls_array[position - 1];
> +}
> +
> +/* { dg-final { scan-assembler "mov(b|zbl)\[ \t\](%fs:)?tls_array@tpoff-1\\(%" } } */

Hi Uros,

Is this OK?

Thanks.

-- 
H.J.



More information about the Gcc-patches mailing list