Skip to content

[BUG] Register dependency not detected with x86 conditional move instructions #104

@dgazzoni

Description

@dgazzoni

Describe the bug
Conditional move instructions behave as if the destination is always overwritten by the source, thus breaking earlier dependencies on the destination. However, the semantics of the instruction are such that if the condition is not true, the destination remains unchanged, and so there should be a dependency on an earlier use of the destination.

For example, consider the following code:

loop:
        add    %ebx,%ebx
        cmove  %ecx,%ebx
        dec    %ebx
        jne    loop

OSACA only detects a dependency from cmove to dec, however, there should be an additional dependency from add to cmove, and a loop-carried dependency from dec to add in the next iteration.

I believe this can be fixed by making the destination register of conditional move instructions to be a source as well. For instance, change line 820 in the current version of osaca/data/isa/x86.yml from

          source: false

to

          source: true

This is just for one of the instruction forms of the cmove instruction; however, it would equally apply to other instruction forms and conditional move instructions with different conditions (e.g. cmova, cmovb, cmovne, etc.)

To Reproduce

OSACA version v 0.5.3
Used where CLI

Save this code to a file, say test.S:

loop:
        add    %ebx,%ebx
        cmove  %ecx,%ebx
        dec    %ebx
        jne    loop

Run the following command to generate a digraph:

osaca --export-graph . test.S

Render the digraph as a figure:

dot -Tpng osaca_dg.dot > osaca_dg.png

OSACA output
This is the digraph generated by the code above with the stock version of osaca/data/isa/x86.yml:

osaca_dg

This the digraph generated by the same code after applying the proposed fix to osaca/data/isa/x86.yml:

osaca_dg2

Note that an additional dependency appears to be missing, from dec to jne. This will be the object of another bug report to come afterwards. Sorry, just learned out about the -f flag.

Expected behavior
The dependency graph should be as in the second figure above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions