+ support SHLX and SHRX in TX86AsmOptimizer.RegLoadedWithNewValue, resolves #39178

(cherry picked from commit 86ac03e07e)

# Conflicts:
#	.gitattributes
This commit is contained in:
florian 2021-07-07 20:28:04 +00:00 committed by Florian Klämpfl
parent 6847e7bfa8
commit 8d6a8e5492
2 changed files with 64 additions and 0 deletions

View File

@ -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
tests/webtbs/tw39178.pp Normal file
View File

@ -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.