I’m currently writing a backend for a specific platform. On the target platform, “add/sub” always write a flag result. I used SDNode pattern “add/sub” for these two instructions, however this leading to a wrongly code as follows,
“add” changes the flag. Desired code is:
… ;No add/sub
Then I tried to use SDNode pattern “addc/subc” instead, but it doesn’t matter and cause some other errors. What should I do to generate code that no “add/sub” between “cmp” and “branch”?
You could model the flag as a register that is modified by cmp/add/sub and read by conditional branches. This should introduce data dependencies that would prevent incorrect scheduling.
I’m not sure what went wrong then, maybe you missed adding these flags somewhere.
I suggest taking a small test-case which has this behavior and pushing it through llc with the -debug flag.Â That should show the instruction graph after many of the selection and scheduling stages.Â Check if the input graph of the scheduling stage indeed now has the new flags register marked as a dependency between the cmp and beq operations.Â That should also show the add and store operations and hopefully demonstrate that the add operations are now also marked as clobering the flags register.