AVX (BMI2) girls are scared of shl/shr
Original Reporter info from Mantis: runewalsh
-
Reporter name:
Original Reporter info from Mantis: runewalsh
- Reporter name:
Description:
(Disregard the ‘girls’ part, it's my local meme.)
Output of the code below is wrong on x86-64 with -CpCOREAVX2 -OoREGVAR.
div 2: 50, 25, 15
shr 1: 1, 1, 15 (should be the same 50, 25, 15)
‘shl’ also fails. ‘UintVec’ can presumably have any length greater than 1 for this to happen, not necessarily 3.
I have a feeling that the same code worked on trunk versions as recent as a month or two ago.
Steps to reproduce:
{$mode objfpc} {$h+} {$modeswitch advancedrecords} {$modeswitch duplicatelocals}
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;
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;
begin
writeln('div 2: ', (UintVec3.Make(100, 50, 30) div 2).ToString);
writeln('shr 1: ', (UintVec3.Make(100, 50, 30) shr 1).ToString);
end.
Mantis conversion info:
- Mantis ID: 39178
- OS: win64
- Build: r49579 [2021/07/06]
- Platform: x86-64
- Version: 3.3.1
- Fixed in version: 3.3.1
- Fixed in revision: 49583 (#86ac03e0)