bagel99 / llvm-my66000

This is a fork of the LLVM project. The code in branch my66000 supports Mitch Alsup's MY66000. The code in branch mcore supports the Motorola MCore.
http://llvm.org
Other
2 stars 2 forks source link

Combining comparisons #33

Closed tkoenig1 closed 2 months ago

tkoenig1 commented 1 year ago

This is a suggestion for improvement for sometime later.

The cmp instruction offers additional results, classifying its first operand as a negative, zero, positive, LONG_MIN or LONG_MAX, plus different combinations, primarily for bounds checking, which can be used for reducing instruction count and register use if the conditions are right.

For example,

_Bool foo (int a, int b)
{
  return a > 0 || a <= b;
}

is now translated to

        cmp     r3,r1,#0
        srl     r3,r3,<1:2>
        cmp     r1,r1,r2
        srl     r1,r1,<1:5>
        or      r1,r3,r1
        ret

but could be something like

        cmp     r1,r1,r2
        srl     r1,r1,<1:5>
        srl     r2,r1,<1:38>  # Or whatever the position of the P bit is, it is undocumented
        or      r1,r1,r2
        ret

This would need some sort of combine pattern (talking gcc terminology here, no idea how this kind of thing would work in LLVM). Similar things could be done using the condition bits for 0 < src1 < src2 etc.

bagel99 commented 1 year ago

This can further be optimized to: cmp r1,r1,r2 srl r1,r1,<1:17> # the FIN bit ret

bagel99 commented 1 year ago

Try again with latest commit e3acd0a206118b47b3ed8ee7f99740f9b32e7e83

bagel99 commented 2 months ago

Upon further reflection: a > 0 || a <= b is not the same as 0 <= a <= b! (Example a=-1). So this is not a range expression. That would be a > 0 && a <= b. If you try _Bool foo (int a, int b) { return a > 0 && a <= b; } the result is cmp r1,r1,r2 srl r1,r1,#25,#1 ret