From 246caf35261dcae10df9f9cc936e129140958bb8 Mon Sep 17 00:00:00 2001
From: Jonas Maebe <jonas@freepascal.org>
Date: Tue, 11 Mar 2014 23:18:45 +0000
Subject: [PATCH]   * never alias/coalesce cpu registers that are not usable by
 the register     allocator (such as stack/framepointers) with virtual
 registers, otherwise     they can get changed in case the virtual register
 gets changed (read-only     use would be ok, but we don't keep track of which
 virtual registers are     only read

git-svn-id: trunk@27104 -
---
 compiler/rgobj.pas | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas
index 4c6f51f6de..1ffed1a52e 100644
--- a/compiler/rgobj.pas
+++ b/compiler/rgobj.pas
@@ -1121,6 +1121,15 @@ unit rgobj;
     procedure trgobj.set_alias(u,v:Tsuperregister);
 
     begin
+      { don't make registers that the register allocator shouldn't touch (such
+        as stack and frame pointers) be aliases for other registers, because
+        then it can propagate them and even start changing them if the aliased
+        register gets changed }
+      if ((u<first_imaginary) and
+          not(u in usable_register_set)) or
+         ((v<first_imaginary) and
+          not(v in usable_register_set)) then
+        exit;
       include(reginfo[v].flags,ri_coalesced);
       if reginfo[v].alias<>0 then
         internalerror(200712291);
@@ -1272,9 +1281,15 @@ unit rgobj;
           add_worklist(u);
           add_worklist(v);
         end
-      {Next test: is it possible and a good idea to coalesce??}
-      else if ((u<first_imaginary) and adjacent_ok(u,v)) or
-              conservative(u,v) then
+      {Next test: is it possible and a good idea to coalesce?? Note: don't
+       coalesce registers that should not be touched by the register allocator,
+       such as stack/framepointers, because otherwise they can be changed }
+      else if (((u<first_imaginary) and adjacent_ok(u,v)) or
+               conservative(u,v)) and
+              ((u>first_imaginary) or
+               (u in usable_register_set)) and
+              ((v>first_imaginary) or
+               (v in usable_register_set)) then
         begin
           m.moveset:=ms_coalesced_moves;  {Move coalesced!}
           coalesced_moves.insert(m);