Hello! We have to return Pmode RTX from legitimize_tls_address. There was a path that returned DImode, when SImode was expected. Since the code deals with various linker bugs, let's leave the generated sequence as-is and just convert it to Pmode before return.
2016-10-18 Uros Bizjak <ubiz...@gmail.com> PR target/77991 * config/i386/i386.c (legitimize_tls_address) <case TLS_MODEL_INITIAL_EXEC>: For TARGET_64BIT || TARGET_ANY_GNU_TLS convert dest to Pmode if different than Pmode. testsuite/ChangeLog: 2016-10-18 Uros Bizjak <ubiz...@gmail.com> PR target/77991 * gcc.target/i386/pr77991.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Patch was committed to mainline SVN and will be backported to other release branches. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 241216) +++ config/i386/i386.c (working copy) @@ -16357,7 +16357,9 @@ legitimize_tls_address (rtx x, enum tls_model mode base = get_thread_pointer (tp_mode, for_mov || !TARGET_TLS_DIRECT_SEG_REFS); off = force_reg (tp_mode, off); - return gen_rtx_PLUS (tp_mode, base, off); + dest = gen_rtx_PLUS (tp_mode, base, off); + if (tp_mode != Pmode) + dest = convert_to_mode (Pmode, dest, 1); } else { Index: testsuite/gcc.target/i386/pr77991.c =================================================================== --- testsuite/gcc.target/i386/pr77991.c (nonexistent) +++ testsuite/gcc.target/i386/pr77991.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -maddress-mode=short" } */ + +struct rcu_reader_data +{ + unsigned ctr; + _Bool waiting; +} + +extern __thread rcu_reader; + +void rcu_read_lock() +{ + struct rcu_reader_data *x = &rcu_reader; + _Bool val = 0; + + __atomic_store(&x->waiting, &val, 0); +}