瀏覽代碼

+ support SHLX and SHRX in TX86AsmOptimizer.RegLoadedWithNewValue, resolves #39178
(cherry picked from commit 86ac03e07eb88209245c46397a124bafb6d87d81)

# Conflicts:
# .gitattributes

florian 4 年之前
父節點
當前提交
8d6a8e5492
共有 2 個文件被更改,包括 64 次插入0 次删除
  1. 7 0
      compiler/x86/aoptx86.pas
  2. 57 0
      tests/webtbs/tw39178.pp

+ 7 - 0
compiler/x86/aoptx86.pas

@@ -842,6 +842,13 @@ unit aoptx86;
             (p.opcode = A_FNSTSW)) and
            (p.oper[0]^.typ=top_reg) and
            Reg1WriteOverwritesReg2Entirely(p.oper[0]^.reg,reg)) or
+          (((p.opcode = A_SHRX) or (p.opcode = A_SHLX)) and
+           (p.ops=3) and
+           (Reg1WriteOverwritesReg2Entirely(p.oper[2]^.reg,reg)) and
+           (((p.oper[1]^.typ=top_reg) and not(Reg1ReadDependsOnReg2(p.oper[1]^.reg,reg))) or
+            ((p.oper[1]^.typ=top_ref) and not(RegInRef(reg,p.oper[1]^.ref^)))) and
+            (((p.oper[0]^.typ=top_reg) and not(Reg1ReadDependsOnReg2(p.oper[0]^.reg,reg))) or
+            ((p.oper[0]^.typ=top_ref) and not(RegInRef(reg,p.oper[0]^.ref^))))) or
           (((p.opcode = A_XOR) or (p.opcode = A_SUB) or (p.opcode = A_SBB)) and
            (p.oper[0]^.typ=top_reg) and (p.oper[1]^.typ=top_reg) and
            (p.oper[0]^.reg=p.oper[1]^.reg) and

+ 57 - 0
tests/webtbs/tw39178.pp

@@ -0,0 +1,57 @@
+{ %cpu=x86_64,i386 }
+{ %opt=-Cpcoreavx2 -O3 }
+{$mode objfpc} {$h+} {$modeswitch advancedrecords} {$modeswitch duplicatelocals}
+uses
+  cpu;
+type
+    UintVec3 = record
+        x, y, z: uint32;
+        class function Make(x, y, z: uint32): UintVec3; static;
+        function ToString: string;
+        class operator shr(const a: UintVec3; b: uint32): UintVec3;
+        class operator div(const a: UintVec3; b: uint32): UintVec3;
+        class operator =(const a,b: UintVec3): Boolean;
+    end;
+
+    class function UintVec3.Make(x, y, z: uint32): UintVec3;
+    begin
+        result.x := x;
+        result.y := y;
+        result.z := z;
+    end;
+
+    function UintVec3.ToString: string;
+    begin
+        WriteStr(result, x, ', ', y, ', ', z);
+    end;
+
+    class operator UintVec3.shr(const a: UintVec3; b: uint32): UintVec3;
+    begin
+        result.x := a.x shr b;
+        result.y := a.y shr b;
+        result.z := a.z shr b;
+    end;
+
+    class operator UintVec3.div(const a: UintVec3; b: uint32): UintVec3;
+    begin
+        result.x := a.x div b;
+        result.y := a.y div b;
+        result.z := a.z div b;
+    end;
+
+    class operator UintVec3.=(const a,b: UintVec3): Boolean;
+    begin
+        result := (a.x = b.x) and
+                  (a.y = b.y) and
+                  (a.z = b.z);
+    end;
+begin
+    if BMI2Support then
+      begin
+        writeln('div 2: ', (UintVec3.Make(100, 50, 30) div 2).ToString);
+        writeln('shr 1: ', (UintVec3.Make(100, 50, 30) shr 1).ToString);
+        if not((UintVec3.Make(100, 50, 30) div 2)=(UintVec3.Make(100, 50, 30) shr 1)) then
+           halt(1);
+        writeln('ok');
+      end;
+end.