Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-10

Bitpacked Record Bug

9 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Willibald Krenn

Hi!

I stumbled accross a bug in fpc that manifests itself when working with bitpacked records that have fields with pos and size mod 8 == 0; For example:

type
   TField = bitpacked record
     case boolean of
     true:  (value : integer);
     false: (
             data: 0 .. $FFFFFF;             // 24 bits
             operation: 0 .. $7F;            // 7 bits
             binop: Boolean                  // one bit
            )
   end;
var
    a, b: integer;
    instr: TField;
begin
   //instr.value := $01000004;
   a := instr.data ; //and $FFFFFF; // bug in fpc
   b := instr.data + 1;
end.

will generate asm like

mov 0x37ab3(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> mov %eax,0x37a8d(%rip) # 0x439000 <U_P$PROJECT1_A> mov 0x37aa7(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> and $0xffffff,%rax
and $0xffffffff,%eax
inc %rax

which is wrong for the first assignment and not very clever for the second one.

I've tracked the issue down to the following check in ncv.pas:

ncv.pas (~ 265)
if equal_defs(p.resultdef,def) and
not is_bitpacked_access(p) then

  p.resultdef:=def

The function is_bitpacked_access (relevant parts) is defined as follows.

in nutils.pas (~ 1155)
subscriptn:
result:= is_packed_record_or_object(tsubscriptnode(n).left.resultdef) and (
(tsubscriptnode(n).vs.vardef.packedbitsize mod 8 0) or

           (tsubscriptnode(n).vs.fieldoffset mod 8 0));

Now, my question is why is an access with a size mod 8 and an offset mod 8 considered NOT bitpacked? Or is the code in ncv.pas to blame?

Cheers,
Willi

Reply by email

Willibald Krenn
to Willibald Krenn

Am 23.10.2010 14:47, schrieb Willibald Krenn:

BTW: Changing is_packed_record to

Show quoted text 6 lines
in nutils.pas (~ 1155) subscriptn: result:= is_packed_record_or_object(tsubscriptnode(n).left.resultdef) and ( (tsubscriptnode(n).vs.vardef.packedbitsize mod 8 0) or (tsubscriptnode(n).vs.fieldoffset mod 8 0));
(tsubscriptnode(n).vs.fieldoffset mod 8  0) or
(tsubscriptnode(n).vs.vardef.packedbitsize mod 24 = 0));

seems to fix the problem on x64.

Willi

Reply by email

Florian Klämpfl
to Willibald Krenn: Hi! I stumbled accross a bug in fpc that manifests itself when working with bitpacked…
Willibald Krenn wrote 57 lines
Hi! I stumbled accross a bug in fpc that manifests itself when working with bitpacked records that have fields with pos and size mod 8 == 0; For example: type TField = bitpacked record case boolean of true: (value : integer); false: ( data: 0 .. $FFFFFF; // 24 bits operation: 0 .. $7F; // 7 bits binop: Boolean // one bit ) end; var a, b: integer; instr: TField; begin //instr.value := $01000004; a := instr.data ; //and $FFFFFF; // bug in fpc b := instr.data + 1; end. will generate asm like mov 0x37ab3(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> mov %eax,0x37a8d(%rip) # 0x439000 <U_P$PROJECT1_A> mov 0x37aa7(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> and $0xffffff,%rax and $0xffffffff,%eax inc %rax which is wrong for the first assignment and not very clever for the second one. I've tracked the issue down to the following check in ncv.pas: ncv.pas (~ 265) if equal_defs(p.resultdef,def) and not is_bitpacked_access(p) then p.resultdef:=def The function is_bitpacked_access (relevant parts) is defined as follows. in nutils.pas (~ 1155) subscriptn: result:= is_packed_record_or_object(tsubscriptnode(n).left.resultdef) and ( (tsubscriptnode(n).vs.vardef.packedbitsize mod 8 0) or (tsubscriptnode(n).vs.fieldoffset mod 8 0)); Now, my question is why is an access with a size mod 8 and an offset mod 8 considered NOT bitpacked? Or is the code in ncv.pas to blame?

I'am not sure about the change, it is Jonas' code. Can you please create a bug report with this information, so it won't be forgotten?

Reply by email

Jonas Maebe
to Willibald Krenn: Hi! I stumbled accross a bug in fpc that manifests itself when working with bitpacked…
Willibald Krenn wrote 8 lines
in nutils.pas (~ 1155) subscriptn: result:= is_packed_record_or_object(tsubscriptnode(n).left.resultdef) and ( (tsubscriptnode(n).vs.vardef.packedbitsize mod 8 0) or (tsubscriptnode(n).vs.fieldoffset mod 8 0)); Now, my question is why is an access with a size mod 8 and an offset mod 8 considered NOT bitpacked?

It should probably check whether the packedbitsize is in [8, 16, 32, 64]. The reason is that if you have a load from a byte-aligned address using a size that is natively supported by the code generator, you don't have to go through all the special-purpose code for bitpacked accesses. 24 bits is however not a size that is natively supported by the code generator, so it has to be treated as a bitpacked access.

Jonas

Reply by email

Willibald Krenn
to Jonas Maebe
Jonas Maebe wrote 7 lines
It should probably check whether the packedbitsize is in [8, 16, 32, 64]. The reason is that if you have a load from a byte-aligned address using a size that is natively supported by the code generator, you don't have to go through all the special-purpose code for bitpacked accesses. 24 bits is however not a size that is natively supported by the code generator, so it has to be treated as a bitpacked access.

Thanks for confirming my thoughts. Shall I still file a bugreport for this?

Somewhat related, I tried to do the following in inline assembly: mov [rax+rcx*type integer], edx
Unfortunately this does not work, although the explicit version (mov [rax+rcx*4], edx works) is ok. Should I file a bug about this too?

Willi

Reply by email

Jonas Maebe
to Willibald Krenn
Willibald Krenn wrote 10 lines
Am 24.10.2010 20:49, schrieb Jonas Maebe: > It should probably check whether the packedbitsize is in [8, 16, 32, > 64]. The reason is that if you have a load from a byte-aligned > address using a size that is natively supported by the code > generator, you don't have to go through all the special-purpose code > for bitpacked accesses. 24 bits is however not a size that is > natively supported by the code generator, so it has to be treated as > a bitpacked access. Thanks for confirming my thoughts. Shall I still file a bugreport for this?

Yes, please.

Somewhat related, I tried to do the following in inline assembly: mov [rax+rcx*type integer], edx Unfortunately this does not work, although the explicit version (mov [rax+rcx*4], edx works) is ok. Should I file a bug about this too?

I guess so, if Delphi supports it.

Jonas

Reply by email

Jonas Maebe
to Willibald Krenn: Thanks for confirming my thoughts. Shall I still file a bugreport for this? Somewhat…
Willibald Krenn wrote 10 lines
Am 24.10.2010 20:49, schrieb Jonas Maebe: > It should probably check whether the packedbitsize is in [8, 16, 32, > 64]. The reason is that if you have a load from a byte-aligned > address using a size that is natively supported by the code > generator, you don't have to go through all the special-purpose code > for bitpacked accesses. 24 bits is however not a size that is > natively supported by the code generator, so it has to be treated as > a bitpacked access. Thanks for confirming my thoughts. Shall I still file a bugreport for this?

It's fixed.

Jonas

Reply by email

Willibald Krenn
to Jonas Maebe
Jonas Maebe wrote
> Thanks for confirming my thoughts. Shall I still file a bugreport for this? It's fixed.

Thanks, I just wanted to file a report for this and the assembly thing but it seems that reporting new issues on mantis does not work currently. (I am getting a blank bug_report_page.php page.)

Willi

Reply by email

Sergei Gorelkin
to Willibald Krenn
Willibald Krenn wrote 11 lines
Am 26.10.2010 21:33, schrieb Jonas Maebe: >> Thanks for confirming my thoughts. Shall I still file a bugreport for >> this? > > It's fixed. > Thanks, I just wanted to file a report for this and the assembly thing but it seems that reporting new issues on mantis does not work currently. (I am getting a blank bug_report_page.php page.)

FPC project uses "advanced view" to report issues
(http://bugs.freepascal.org/bug_report_advanced_page.php), while Lazarus project uses regular view (http://bugs.freepascal.org/bug_report_page.php). Opening the latter URL while project is set to FPC indeed results in a blank page. Many people complain about this.

Regards,
Sergei

Reply by email