diff mbox series

rs6000: replace '(const_int 0)' to 'unspec:BLK [(const_int 0)]' for stack_tie

Message ID 20230612131919.269681-1-guojiufu@linux.ibm.com
State New
Headers show
Series rs6000: replace '(const_int 0)' to 'unspec:BLK [(const_int 0)]' for stack_tie | expand

Commit Message

Jiufu Guo June 12, 2023, 1:19 p.m. UTC
Hi,

For stack_tie, currently below insn is generated:
(insn 15 14 16 3 (parallel [
             (set (mem/c:BLK (reg/f:DI 1 1) [1  A8])
                 (const_int 0 [0]))
         ]) "/home/guojiufu/temp/gdb.c":13:3 922 {stack_tie}
      (nil))

It is "set (mem/c:BLK (reg/f:DI 1 1) (const_int 0 [0])".  This maybe
looks like "a memory block is zerored", while actually stack_tie
may be more like a placeholder, and does not generate any thing.

To avoid potential misunderstand, "UNPSEC:BLK [(const_int 0)].." could
be used here like other ports.

This patch does this.  Bootstrap&regtest pass on ppc64{,le}.
Is this ok for trunk?

BR,
Jeff (Jiufu Guo)

---
 gcc/config/rs6000/predicates.md   | 11 +++++++----
 gcc/config/rs6000/rs6000-logue.cc |  4 +++-
 gcc/config/rs6000/rs6000.cc       |  4 ++++
 gcc/config/rs6000/rs6000.md       | 14 ++++++++++----
 4 files changed, 24 insertions(+), 9 deletions(-)

Comments

David Edelsohn June 13, 2023, 12:24 a.m. UTC | #1
Hi, Jiufu

This definitely seems to be a better solution.

The TARGET_CONST_ANCHOR change should not be part of this patch.  Also
there is no ChangeLog for the patch.

This generally looks correct and consistent with other ports. I want
to give Segher a chance to double check it, if he wishes.

Thanks David

On Mon, Jun 12, 2023 at 9:19 AM Jiufu Guo <guojiufu@linux.ibm.com> wrote:
>
> Hi,
>
> For stack_tie, currently below insn is generated:
> (insn 15 14 16 3 (parallel [
>              (set (mem/c:BLK (reg/f:DI 1 1) [1  A8])
>                  (const_int 0 [0]))
>          ]) "/home/guojiufu/temp/gdb.c":13:3 922 {stack_tie}
>       (nil))
>
> It is "set (mem/c:BLK (reg/f:DI 1 1) (const_int 0 [0])".  This maybe
> looks like "a memory block is zerored", while actually stack_tie
> may be more like a placeholder, and does not generate any thing.
>
> To avoid potential misunderstand, "UNPSEC:BLK [(const_int 0)].." could
> be used here like other ports.
>
> This patch does this.  Bootstrap&regtest pass on ppc64{,le}.
> Is this ok for trunk?
>
> BR,
> Jeff (Jiufu Guo)
>
> ---
>  gcc/config/rs6000/predicates.md   | 11 +++++++----
>  gcc/config/rs6000/rs6000-logue.cc |  4 +++-
>  gcc/config/rs6000/rs6000.cc       |  4 ++++
>  gcc/config/rs6000/rs6000.md       | 14 ++++++++++----
>  4 files changed, 24 insertions(+), 9 deletions(-)
>
> diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
> index a16ee30f0c0..4748cb37ce8 100644
> --- a/gcc/config/rs6000/predicates.md
> +++ b/gcc/config/rs6000/predicates.md
> @@ -1854,10 +1854,13 @@ (define_predicate "stmw_operation"
>  (define_predicate "tie_operand"
>    (match_code "parallel")
>  {
> -  return (GET_CODE (XVECEXP (op, 0, 0)) == SET
> -         && MEM_P (XEXP (XVECEXP (op, 0, 0), 0))
> -         && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode
> -         && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx);
> +  rtx set = XVECEXP (op, 0, 0);
> +  return (GET_CODE (set) == SET
> +         && MEM_P (SET_DEST (set))
> +         && GET_MODE (SET_DEST (set)) == BLKmode
> +         && GET_CODE (SET_SRC (set)) == UNSPEC
> +         && XINT (SET_SRC (set), 1) == UNSPEC_TIE
> +         && XVECEXP (SET_SRC (set), 0, 0) == const0_rtx);
>  })
>
>  ;; Match a small code model toc reference (or medium and large
> diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc
> index bc6b153b59f..b99f43a8282 100644
> --- a/gcc/config/rs6000/rs6000-logue.cc
> +++ b/gcc/config/rs6000/rs6000-logue.cc
> @@ -1463,7 +1463,9 @@ rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed)
>    while (--i >= 0)
>      {
>        rtx mem = gen_frame_mem (BLKmode, regs[i]);
> -      RTVEC_ELT (p, i) = gen_rtx_SET (mem, const0_rtx);
> +      RTVEC_ELT (p, i)
> +       = gen_rtx_SET (mem, gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, const0_rtx),
> +                                           UNSPEC_TIE));
>      }
>
>    emit_insn (gen_stack_tie (gen_rtx_PARALLEL (VOIDmode, p)));
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index d197c3f3289..0c81ebea711 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -1760,6 +1760,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
>
>  #undef TARGET_UPDATE_IPA_FN_TARGET_INFO
>  #define TARGET_UPDATE_IPA_FN_TARGET_INFO rs6000_update_ipa_fn_target_info
> +
> +#undef TARGET_CONST_ANCHOR
> +#define TARGET_CONST_ANCHOR 0x8000
> +
>
>
>  /* Processor table.  */
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index b0db8ae508d..fdcf8347812 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -158,6 +158,7 @@ (define_c_enum "unspec"
>     UNSPEC_HASHCHK
>     UNSPEC_XXSPLTIDP_CONST
>     UNSPEC_XXSPLTIW_CONST
> +   UNSPEC_TIE
>    ])
>
>  ;;
> @@ -10828,7 +10829,9 @@ (define_expand "restore_stack_block"
>    operands[4] = gen_frame_mem (Pmode, operands[1]);
>    p = rtvec_alloc (1);
>    RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
> -                                 const0_rtx);
> +                                 gen_rtx_UNSPEC (BLKmode,
> +                                                 gen_rtvec (1, const0_rtx),
> +                                                 UNSPEC_TIE));
>    operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
>  })
>
> @@ -10866,7 +10869,9 @@ (define_expand "restore_stack_nonlocal"
>    operands[5] = gen_frame_mem (Pmode, operands[3]);
>    p = rtvec_alloc (1);
>    RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
> -                                 const0_rtx);
> +                                 gen_rtx_UNSPEC (BLKmode,
> +                                                 gen_rtvec (1, const0_rtx),
> +                                                 UNSPEC_TIE));
>    operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
>  })
>
> @@ -13898,7 +13903,8 @@ (define_insn "*save_fpregs_<mode>_r1"
>  ; not be moved over loads from or stores to stack memory.
>  (define_insn "stack_tie"
>    [(match_parallel 0 "tie_operand"
> -                  [(set (mem:BLK (reg 1)) (const_int 0))])]
> +                  [(set (mem:BLK (reg 1))
> +                   (unspec:BLK [(const_int 0)] UNSPEC_TIE))])]
>    ""
>    ""
>    [(set_attr "length" "0")])
> @@ -13910,7 +13916,7 @@ (define_insn "stack_restore_tie"
>    [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
>         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
>                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
> -   (set (mem:BLK (scratch)) (const_int 0))]
> +   (set (mem:BLK (scratch)) (unspec:BLK [(const_int 0)] UNSPEC_TIE))]
>    "TARGET_32BIT"
>    "@
>     mr %0,%1
> --
> 2.39.3
>
Jiufu Guo June 13, 2023, 2:15 a.m. UTC | #2
Hi David,

David Edelsohn <dje.gcc@gmail.com> writes:

> Hi, Jiufu
>
> This definitely seems to be a better solution.
>
> The TARGET_CONST_ANCHOR change should not be part of this patch.  Also
> there is no ChangeLog for the patch.

Thanks a lot for your quick review!! And sorry for the sending this patch
in a hurry.  I would update the patch accordingly.


BR,
Jeff (Jiufu Guo)

>
> This generally looks correct and consistent with other ports. I want
> to give Segher a chance to double check it, if he wishes.
>
> Thanks David
>
> On Mon, Jun 12, 2023 at 9:19 AM Jiufu Guo <guojiufu@linux.ibm.com> wrote:
>>
>> Hi,
>>
>> For stack_tie, currently below insn is generated:
>> (insn 15 14 16 3 (parallel [
>>              (set (mem/c:BLK (reg/f:DI 1 1) [1  A8])
>>                  (const_int 0 [0]))
>>          ]) "/home/guojiufu/temp/gdb.c":13:3 922 {stack_tie}
>>       (nil))
>>
>> It is "set (mem/c:BLK (reg/f:DI 1 1) (const_int 0 [0])".  This maybe
>> looks like "a memory block is zerored", while actually stack_tie
>> may be more like a placeholder, and does not generate any thing.
>>
>> To avoid potential misunderstand, "UNPSEC:BLK [(const_int 0)].." could
>> be used here like other ports.
>>
>> This patch does this.  Bootstrap&regtest pass on ppc64{,le}.
>> Is this ok for trunk?
>>
>> BR,
>> Jeff (Jiufu Guo)
>>
>> ---
>>  gcc/config/rs6000/predicates.md   | 11 +++++++----
>>  gcc/config/rs6000/rs6000-logue.cc |  4 +++-
>>  gcc/config/rs6000/rs6000.cc       |  4 ++++
>>  gcc/config/rs6000/rs6000.md       | 14 ++++++++++----
>>  4 files changed, 24 insertions(+), 9 deletions(-)
>>
>> diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
>> index a16ee30f0c0..4748cb37ce8 100644
>> --- a/gcc/config/rs6000/predicates.md
>> +++ b/gcc/config/rs6000/predicates.md
>> @@ -1854,10 +1854,13 @@ (define_predicate "stmw_operation"
>>  (define_predicate "tie_operand"
>>    (match_code "parallel")
>>  {
>> -  return (GET_CODE (XVECEXP (op, 0, 0)) == SET
>> -         && MEM_P (XEXP (XVECEXP (op, 0, 0), 0))
>> -         && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode
>> -         && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx);
>> +  rtx set = XVECEXP (op, 0, 0);
>> +  return (GET_CODE (set) == SET
>> +         && MEM_P (SET_DEST (set))
>> +         && GET_MODE (SET_DEST (set)) == BLKmode
>> +         && GET_CODE (SET_SRC (set)) == UNSPEC
>> +         && XINT (SET_SRC (set), 1) == UNSPEC_TIE
>> +         && XVECEXP (SET_SRC (set), 0, 0) == const0_rtx);
>>  })
>>
>>  ;; Match a small code model toc reference (or medium and large
>> diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc
>> index bc6b153b59f..b99f43a8282 100644
>> --- a/gcc/config/rs6000/rs6000-logue.cc
>> +++ b/gcc/config/rs6000/rs6000-logue.cc
>> @@ -1463,7 +1463,9 @@ rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed)
>>    while (--i >= 0)
>>      {
>>        rtx mem = gen_frame_mem (BLKmode, regs[i]);
>> -      RTVEC_ELT (p, i) = gen_rtx_SET (mem, const0_rtx);
>> +      RTVEC_ELT (p, i)
>> +       = gen_rtx_SET (mem, gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, const0_rtx),
>> +                                           UNSPEC_TIE));
>>      }
>>
>>    emit_insn (gen_stack_tie (gen_rtx_PARALLEL (VOIDmode, p)));
>> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
>> index d197c3f3289..0c81ebea711 100644
>> --- a/gcc/config/rs6000/rs6000.cc
>> +++ b/gcc/config/rs6000/rs6000.cc
>> @@ -1760,6 +1760,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
>>
>>  #undef TARGET_UPDATE_IPA_FN_TARGET_INFO
>>  #define TARGET_UPDATE_IPA_FN_TARGET_INFO rs6000_update_ipa_fn_target_info
>> +
>> +#undef TARGET_CONST_ANCHOR
>> +#define TARGET_CONST_ANCHOR 0x8000
>> +
>>
>>
>>  /* Processor table.  */
>> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
>> index b0db8ae508d..fdcf8347812 100644
>> --- a/gcc/config/rs6000/rs6000.md
>> +++ b/gcc/config/rs6000/rs6000.md
>> @@ -158,6 +158,7 @@ (define_c_enum "unspec"
>>     UNSPEC_HASHCHK
>>     UNSPEC_XXSPLTIDP_CONST
>>     UNSPEC_XXSPLTIW_CONST
>> +   UNSPEC_TIE
>>    ])
>>
>>  ;;
>> @@ -10828,7 +10829,9 @@ (define_expand "restore_stack_block"
>>    operands[4] = gen_frame_mem (Pmode, operands[1]);
>>    p = rtvec_alloc (1);
>>    RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
>> -                                 const0_rtx);
>> +                                 gen_rtx_UNSPEC (BLKmode,
>> +                                                 gen_rtvec (1, const0_rtx),
>> +                                                 UNSPEC_TIE));
>>    operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
>>  })
>>
>> @@ -10866,7 +10869,9 @@ (define_expand "restore_stack_nonlocal"
>>    operands[5] = gen_frame_mem (Pmode, operands[3]);
>>    p = rtvec_alloc (1);
>>    RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
>> -                                 const0_rtx);
>> +                                 gen_rtx_UNSPEC (BLKmode,
>> +                                                 gen_rtvec (1, const0_rtx),
>> +                                                 UNSPEC_TIE));
>>    operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
>>  })
>>
>> @@ -13898,7 +13903,8 @@ (define_insn "*save_fpregs_<mode>_r1"
>>  ; not be moved over loads from or stores to stack memory.
>>  (define_insn "stack_tie"
>>    [(match_parallel 0 "tie_operand"
>> -                  [(set (mem:BLK (reg 1)) (const_int 0))])]
>> +                  [(set (mem:BLK (reg 1))
>> +                   (unspec:BLK [(const_int 0)] UNSPEC_TIE))])]
>>    ""
>>    ""
>>    [(set_attr "length" "0")])
>> @@ -13910,7 +13916,7 @@ (define_insn "stack_restore_tie"
>>    [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
>>         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
>>                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
>> -   (set (mem:BLK (scratch)) (const_int 0))]
>> +   (set (mem:BLK (scratch)) (unspec:BLK [(const_int 0)] UNSPEC_TIE))]
>>    "TARGET_32BIT"
>>    "@
>>     mr %0,%1
>> --
>> 2.39.3
>>
Segher Boessenkool June 13, 2023, 6:14 p.m. UTC | #3
Hi!

On Tue, Jun 13, 2023 at 10:15:49AM +0800, Jiufu Guo wrote:
> David Edelsohn <dje.gcc@gmail.com> writes:
> >
> > This definitely seems to be a better solution.
> >
> > The TARGET_CONST_ANCHOR change should not be part of this patch.  Also
> > there is no ChangeLog for the patch.
> 
> Thanks a lot for your quick review!! And sorry for the sending this patch
> in a hurry.  I would update the patch accordingly.

> > This generally looks correct and consistent with other ports. I want
> > to give Segher a chance to double check it, if he wishes.

The documentation is very clear that the only thing for which you can
have BLKmode is "mem".  Not unspec, only "mem".

Let's not do this.  The existing code has clear and obvious semantics,
which is documented as well -- there is no reason to make it worse in
every respect!


Segher
David Edelsohn June 13, 2023, 6:59 p.m. UTC | #4
On Tue, Jun 13, 2023 at 2:16 PM Segher Boessenkool
<segher@kernel.crashing.org> wrote:
>
> Hi!
>
> On Tue, Jun 13, 2023 at 10:15:49AM +0800, Jiufu Guo wrote:
> > David Edelsohn <dje.gcc@gmail.com> writes:
> > >
> > > This definitely seems to be a better solution.
> > >
> > > The TARGET_CONST_ANCHOR change should not be part of this patch.  Also
> > > there is no ChangeLog for the patch.
> >
> > Thanks a lot for your quick review!! And sorry for the sending this patch
> > in a hurry.  I would update the patch accordingly.
>
> > > This generally looks correct and consistent with other ports. I want
> > > to give Segher a chance to double check it, if he wishes.
>
> The documentation is very clear that the only thing for which you can
> have BLKmode is "mem".  Not unspec, only "mem".
>
> Let's not do this.  The existing code has clear and obvious semantics,
> which is documented as well -- there is no reason to make it worse in
> every respect.

Segher,

Unfortunately, GCC now is inconsistent and this response is incorrect.
The documentation is out of date or was ignored and the "facts on the
ground" contradict your review.

Yes, (const_int 0) is supposed to be a general no-op and BLKmode only
is supposed to be used for MEM, but other major targets (arm, aarch64,
riscv, s390) all use unspec:BLK and specifically UNSPEC_TIE.  rs6000
is the only port that does not follow this convention.  The middle-end
has adapted to the behavior of all of the other targets, whether that
conformed to the documentation or not.  The rs6000 port needs to be
fixed and Jiufu's approach is the correct one, consistent with all
other targets for stack tie.  If the documentation differs, the
documentation needs to be updated, not a different approach for the
rs6000 port.  Jiufu's patch is correct.

Thanks, David
Jiufu Guo June 14, 2023, 3 a.m. UTC | #5
Hi Segher, David,

David Edelsohn <dje.gcc@gmail.com> writes:

> On Tue, Jun 13, 2023 at 2:16 PM Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
>>
>> Hi!
>>
>> On Tue, Jun 13, 2023 at 10:15:49AM +0800, Jiufu Guo wrote:
>> > David Edelsohn <dje.gcc@gmail.com> writes:
>> > >
>> > > This definitely seems to be a better solution.
>> > >
>> > > The TARGET_CONST_ANCHOR change should not be part of this patch.  Also
>> > > there is no ChangeLog for the patch.
>> >
>> > Thanks a lot for your quick review!! And sorry for the sending this patch
>> > in a hurry.  I would update the patch accordingly.
>>
>> > > This generally looks correct and consistent with other ports. I want
>> > > to give Segher a chance to double check it, if he wishes.
>>
>> The documentation is very clear that the only thing for which you can
>> have BLKmode is "mem".  Not unspec, only "mem".
>>
>> Let's not do this.  The existing code has clear and obvious semantics,
>> which is documented as well -- there is no reason to make it worse in
>> every respect.

Thanks for all your insight comments!

Yeap, while "unspec:BLK" is very widely used already on various ports.
And it seems a few place is using BLKmode without strictly align with
the document :( It would not be very good thing, but maybe no better
solutions.

For existing code "set (mem/c:BLK (reg/f:DI 1 1) (const_int 0 [0])"
Since it is a set, the operand set_src should be valid for
the mode of the set_dest. While set_src is 'const_int 0'.
And this 'set' may be mis-readed as 'a memory is zeroed' or
'no-op to a mem'. Using unspec here would just say this is an special
operation instead a normal 'const_int 0'.

BR,
Jeff (Jiufu Guo)

>
> Segher,
>
> Unfortunately, GCC now is inconsistent and this response is incorrect.
> The documentation is out of date or was ignored and the "facts on the
> ground" contradict your review.
>
> Yes, (const_int 0) is supposed to be a general no-op and BLKmode only
> is supposed to be used for MEM, but other major targets (arm, aarch64,
> riscv, s390) all use unspec:BLK and specifically UNSPEC_TIE.  rs6000
> is the only port that does not follow this convention.  The middle-end
> has adapted to the behavior of all of the other targets, whether that
> conformed to the documentation or not.  The rs6000 port needs to be
> fixed and Jiufu's approach is the correct one, consistent with all
> other targets for stack tie.  If the documentation differs, the
> documentation needs to be updated, not a different approach for the
> rs6000 port.  Jiufu's patch is correct.
>
> Thanks, David
diff mbox series

Patch

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index a16ee30f0c0..4748cb37ce8 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1854,10 +1854,13 @@  (define_predicate "stmw_operation"
 (define_predicate "tie_operand"
   (match_code "parallel")
 {
-  return (GET_CODE (XVECEXP (op, 0, 0)) == SET
-	  && MEM_P (XEXP (XVECEXP (op, 0, 0), 0))
-	  && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode
-	  && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx);
+  rtx set = XVECEXP (op, 0, 0);
+  return (GET_CODE (set) == SET
+	  && MEM_P (SET_DEST (set))
+	  && GET_MODE (SET_DEST (set)) == BLKmode
+	  && GET_CODE (SET_SRC (set)) == UNSPEC
+	  && XINT (SET_SRC (set), 1) == UNSPEC_TIE
+	  && XVECEXP (SET_SRC (set), 0, 0) == const0_rtx);
 })
 
 ;; Match a small code model toc reference (or medium and large
diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc
index bc6b153b59f..b99f43a8282 100644
--- a/gcc/config/rs6000/rs6000-logue.cc
+++ b/gcc/config/rs6000/rs6000-logue.cc
@@ -1463,7 +1463,9 @@  rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed)
   while (--i >= 0)
     {
       rtx mem = gen_frame_mem (BLKmode, regs[i]);
-      RTVEC_ELT (p, i) = gen_rtx_SET (mem, const0_rtx);
+      RTVEC_ELT (p, i)
+	= gen_rtx_SET (mem, gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, const0_rtx),
+					    UNSPEC_TIE));
     }
 
   emit_insn (gen_stack_tie (gen_rtx_PARALLEL (VOIDmode, p)));
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d197c3f3289..0c81ebea711 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1760,6 +1760,10 @@  static const struct attribute_spec rs6000_attribute_table[] =
 
 #undef TARGET_UPDATE_IPA_FN_TARGET_INFO
 #define TARGET_UPDATE_IPA_FN_TARGET_INFO rs6000_update_ipa_fn_target_info
+
+#undef TARGET_CONST_ANCHOR
+#define TARGET_CONST_ANCHOR 0x8000
+
 
 
 /* Processor table.  */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index b0db8ae508d..fdcf8347812 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -158,6 +158,7 @@  (define_c_enum "unspec"
    UNSPEC_HASHCHK
    UNSPEC_XXSPLTIDP_CONST
    UNSPEC_XXSPLTIW_CONST
+   UNSPEC_TIE
   ])
 
 ;;
@@ -10828,7 +10829,9 @@  (define_expand "restore_stack_block"
   operands[4] = gen_frame_mem (Pmode, operands[1]);
   p = rtvec_alloc (1);
   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
-				  const0_rtx);
+				  gen_rtx_UNSPEC (BLKmode,
+						  gen_rtvec (1, const0_rtx),
+						  UNSPEC_TIE));
   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
 })
 
@@ -10866,7 +10869,9 @@  (define_expand "restore_stack_nonlocal"
   operands[5] = gen_frame_mem (Pmode, operands[3]);
   p = rtvec_alloc (1);
   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
-				  const0_rtx);
+				  gen_rtx_UNSPEC (BLKmode,
+						  gen_rtvec (1, const0_rtx),
+						  UNSPEC_TIE));
   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
 })
 
@@ -13898,7 +13903,8 @@  (define_insn "*save_fpregs_<mode>_r1"
 ; not be moved over loads from or stores to stack memory.
 (define_insn "stack_tie"
   [(match_parallel 0 "tie_operand"
-		   [(set (mem:BLK (reg 1)) (const_int 0))])]
+		   [(set (mem:BLK (reg 1))
+		    (unspec:BLK [(const_int 0)] UNSPEC_TIE))])]
   ""
   ""
   [(set_attr "length" "0")])
@@ -13910,7 +13916,7 @@  (define_insn "stack_restore_tie"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 		 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
-   (set (mem:BLK (scratch)) (const_int 0))]
+   (set (mem:BLK (scratch)) (unspec:BLK [(const_int 0)] UNSPEC_TIE))]
   "TARGET_32BIT"
   "@
    mr %0,%1