mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 09:28:48 +02:00
* use bzhi only (if at all) for in_and_assign_x_y and not other in_*_x_y operations, resolves #40016
This commit is contained in:
parent
a1a2549cf1
commit
96d4bd19ac
@ -636,7 +636,7 @@ implementation
|
||||
opsize := def_cgsize(loadnode.resultdef);
|
||||
|
||||
{ BMI2 optimisations }
|
||||
if (CPUX86_HAS_BMI2 in cpu_capabilities[current_settings.cputype]) then
|
||||
if (CPUX86_HAS_BMI2 in cpu_capabilities[current_settings.cputype]) and (inlinenumber=in_and_assign_x_y) then
|
||||
begin
|
||||
{ If the second operand is "((1 shl y) - 1)", we can turn it
|
||||
into a BZHI operator instead }
|
||||
|
39
tests/webtbs/tw40016.pp
Normal file
39
tests/webtbs/tw40016.pp
Normal file
@ -0,0 +1,39 @@
|
||||
{ %CPU=x86_64 }
|
||||
{ %opt=-Cpcoreavx2 -O4 }
|
||||
uses
|
||||
cpu;
|
||||
|
||||
procedure Verify(const op: string; got, expected: SizeUint);
|
||||
begin
|
||||
write('%10101010 ' + op + ' %111 = %' + BinStr(got, 1 + BsrQWord(got or 1)));
|
||||
if got = expected then
|
||||
writeln(' - ok')
|
||||
else
|
||||
begin
|
||||
writeln(' - FAIL, must be %' + BinStr(expected, 1 + BsrQWord(expected or 1)));
|
||||
halt(1);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
b, nbits: SizeUint;
|
||||
|
||||
|
||||
begin
|
||||
if BMI2Support then
|
||||
begin
|
||||
nbits := 3 + random(0);
|
||||
|
||||
b := %10101010 + random(0);
|
||||
b := b or (SizeUint(1) shl nbits - 1);
|
||||
Verify('or', b, %10101111);
|
||||
|
||||
b := %10101010 + random(0);
|
||||
b := b xor (SizeUint(1) shl nbits - 1);
|
||||
Verify('xor', b, %10101101);
|
||||
|
||||
b := %10101010 + random(0);
|
||||
b := b and (SizeUint(1) shl nbits - 1);
|
||||
Verify('and', b, %10);
|
||||
end;
|
||||
end.
|
Loading…
Reference in New Issue
Block a user