diff -urpN a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c --- a/gcc/config/aarch64/aarch64.c 2018-10-09 11:49:19.000000000 +0800 +++ b/gcc/config/aarch64/aarch64.c 2018-10-09 13:42:15.000000000 +0800 @@ -1619,7 +1619,7 @@ aarch64_load_symref_appropriately (rtx d case SYMBOL_SMALL_TLSDESC: { machine_mode mode = GET_MODE (dest); - rtx x0 = gen_rtx_REG (mode, R0_REGNUM); + rtx x0 = gen_rtx_REG (ptr_mode, R0_REGNUM); rtx tp; gcc_assert (mode == Pmode || mode == ptr_mode); @@ -1635,6 +1635,11 @@ aarch64_load_symref_appropriately (rtx d if (mode != Pmode) tp = gen_lowpart (mode, tp); + if (mode != ptr_mode) + { + x0 = force_reg (mode, gen_rtx_SIGN_EXTEND (mode, x0)); + } + emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, tp, x0))); set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); return;