瀏覽代碼

* arm/a64: Be more careful about hp1 and p_second being null in "TryConstMerge"

J. Gareth "Curious Kit" Moreton 2 月之前
父節點
當前提交
5646d14a3c
共有 1 個文件被更改,包括 27 次插入7 次删除
  1. 27 7
      compiler/armgen/aoptarm.pas

+ 27 - 7
compiler/armgen/aoptarm.pas

@@ -2026,19 +2026,22 @@ Implementation
       procedure SearchAhead;
       procedure SearchAhead;
         begin
         begin
           { If p.opcode = A_STR, then ThisReg will be NR_NO }
           { If p.opcode = A_STR, then ThisReg will be NR_NO }
-          if (
+          if
 {$ifdef ARM}
 {$ifdef ARM}
-              MatchInstruction(p_second, A_MOV, [taicpu(p).condition], []) or
-              MatchInstruction(p_second, A_MOVW, [taicpu(p).condition], [])
+            Assigned(hp1) and
 {$endif ARM}
 {$endif ARM}
 {$ifdef AARCH64}
 {$ifdef AARCH64}
-              MatchInstruction(p, A_MOVZ, []) or
+            (
+              (
+                MatchInstruction(p, A_MOVZ, []) and
+                Assigned(hp1)
+              ) or
               (
               (
                 MatchInstruction(p, A_STR, []) and
                 MatchInstruction(p, A_STR, []) and
                 SetAndTest(p, hp1)
                 SetAndTest(p, hp1)
               )
               )
-{$endif AARCH64}
             ) and
             ) and
+{$endif AARCH64}
             (
             (
               (
               (
                 (ThisReg <> NR_NO) and
                 (ThisReg <> NR_NO) and
@@ -2254,6 +2257,7 @@ Implementation
                                                             Result := True;
                                                             Result := True;
 {$ifdef AARCH64}
 {$ifdef AARCH64}
                                                             { Searching ahead only benefits AArch64 here }
                                                             { Searching ahead only benefits AArch64 here }
+                                                            hp1 := hp2; { Since hp2 now appears immediately after p }
                                                             SearchAhead;
                                                             SearchAhead;
 {$endif AARCH64}
 {$endif AARCH64}
                                                             Exit;
                                                             Exit;
@@ -2389,6 +2393,7 @@ Implementation
                                                     if (taicpu(p).oper[1]^.val < 0) or (taicpu(p).oper[1]^.val > 256) then
                                                     if (taicpu(p).oper[1]^.val < 0) or (taicpu(p).oper[1]^.val > 256) then
                                                       taicpu(p).opcode := A_MOVW;
                                                       taicpu(p).opcode := A_MOVW;
 {$endif ARM}
 {$endif ARM}
+                                                    taicpu(hp1).oppostfix := PF_None;
                                                   end
                                                   end
                                                 else
                                                 else
                                                   begin
                                                   begin
@@ -2410,11 +2415,15 @@ Implementation
                                                     taicpu(p).oper[0]^.reg := ThisReg;
                                                     taicpu(p).oper[0]^.reg := ThisReg;
                                                     taicpu(p_second).oper[0]^.reg := ThisReg;
                                                     taicpu(p_second).oper[0]^.reg := ThisReg;
                                                     taicpu(hp1).oper[0]^.reg := ThisReg;
                                                     taicpu(hp1).oper[0]^.reg := ThisReg;
+{$endif AARCH64}
+                                                    taicpu(hp1).oppostfix := PF_None;
+{$ifdef AARCH64}
+                                                    hp1 := p_second; { Since p_second now appears immediately after p }
+                                                    p_second := hp1;
 {$endif AARCH64}
 {$endif AARCH64}
                                                     { TODO: Confirm that the A_MOVZ / A_MOVK combination is the most efficient }
                                                     { TODO: Confirm that the A_MOVZ / A_MOVK combination is the most efficient }
                                                   end;
                                                   end;
 
 
-                                                taicpu(hp1).oppostfix := PF_None;
                                                 RemoveInstruction(hp1_second);
                                                 RemoveInstruction(hp1_second);
                                                 Result := True;
                                                 Result := True;
                                               end;
                                               end;
@@ -2476,6 +2485,7 @@ Implementation
 {$ifdef AARCH64}
 {$ifdef AARCH64}
                 A_MOVK:
                 A_MOVK:
                   if (getsubreg(ThisReg) = R_SUBD) and
                   if (getsubreg(ThisReg) = R_SUBD) and
+                    Assigned(hp1) and
                     (taicpu(hp1).oper[0]^.reg = ThisReg) and
                     (taicpu(hp1).oper[0]^.reg = ThisReg) and
                     (taicpu(hp1).ops = 3) and
                     (taicpu(hp1).ops = 3) and
                     (taicpu(hp1).oper[2]^.shifterop^.shiftmode = SM_LSL) and
                     (taicpu(hp1).oper[2]^.shifterop^.shiftmode = SM_LSL) and
@@ -2707,6 +2717,8 @@ Implementation
                                       DebugMsg(SPeepholeOptimization + 'Merged two zero-register byte-writes to memory into a single zero-register half-write (StrbStrb2Strh)', p);
                                       DebugMsg(SPeepholeOptimization + 'Merged two zero-register byte-writes to memory into a single zero-register half-write (StrbStrb2Strh)', p);
                                       taicpu(p).oppostfix := PF_H;
                                       taicpu(p).oppostfix := PF_H;
                                       RemoveInstruction(p_second);
                                       RemoveInstruction(p_second);
+                                      if hp1 = p_second then { Make sure hp1 deson't become a dangling pointer }
+                                        GetNextInstruction(p, hp1);
                                       Result := True;
                                       Result := True;
                                     end;
                                     end;
                                 end;
                                 end;
@@ -2810,6 +2822,8 @@ Implementation
 
 
                                       taicpu(p).oppostfix := PF_None;
                                       taicpu(p).oppostfix := PF_None;
                                       RemoveInstruction(p_second);
                                       RemoveInstruction(p_second);
+                                      if hp1 = p_second then { Make sure hp1 deson't become a dangling pointer }
+                                        GetNextInstruction(p, hp1);
                                       Result := True;
                                       Result := True;
                                     end;
                                     end;
                                 end;
                                 end;
@@ -2868,7 +2882,11 @@ Implementation
 
 
                                         { If the 3rd word is zero, we can remove the instruction entirely }
                                         { If the 3rd word is zero, we can remove the instruction entirely }
                                         if taicpu(p_second).oper[1]^.val = 0 then
                                         if taicpu(p_second).oper[1]^.val = 0 then
-                                          RemoveInstruction(p_second)
+                                          begin
+                                            RemoveInstruction(p_second);
+                                            if hp1 = p_second then { Make sure hp1 deson't become a dangling pointer }
+                                              GetNextInstruction(p, hp1);
+                                          end
                                         else
                                         else
                                           begin
                                           begin
                                             so.shiftmode := SM_LSL;
                                             so.shiftmode := SM_LSL;
@@ -2910,6 +2928,8 @@ Implementation
                                       DebugMsg(SPeepholeOptimization + 'Merged two zero-register word-writes to memory into a single zero-register extended-write (StrStr2Str)', p);
                                       DebugMsg(SPeepholeOptimization + 'Merged two zero-register word-writes to memory into a single zero-register extended-write (StrStr2Str)', p);
                                       taicpu(p).oper[0]^.reg := NR_XZR;
                                       taicpu(p).oper[0]^.reg := NR_XZR;
                                       RemoveInstruction(p_second);
                                       RemoveInstruction(p_second);
+                                      if hp1 = p_second then { Make sure hp1 deson't become a dangling pointer }
+                                        GetNextInstruction(p, hp1);
                                       Result := True;
                                       Result := True;
                                     end;
                                     end;
                                 end;
                                 end;