-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Division and modulo by power of 2 don't get picked up on MWCC 1.3.2 and higher #276
Comments
Yes!
Depends on how complicated it would be to do it on a higher level; if it's easy then it could generalize better across compilers/compiler versions. Assembly patterns have the downside of breaking when the instructions aren't next to each other. For some compilers this means they aren't very reliable (but they are easy to write and can handle branches which other pattern matching subsystems can't). IR patterns are better in this regard and look more or less the same.
Sure, just add the asm in some file in tests/end_to_end/, with a -flags.txt file that indicates ppc. They can go in the same directory (I think we have an existing division-by-power-of-two one?) with filenames denoting compiler. |
Happy to take the tests even without a fix, btw |
I already made a primitive fix with the cases I listed here. I will check them on all MWCC versions I have and look for patterns in the asm and the higher level interpretation.
Yes, we already have a test for it, I might extend it because division by 2 is different from power of 2 in some versions. I might pick a candidate for every version that generates a different asm. |
For low level replacements we have ASM and IR patterns, what do we have for higher level simplifications? |
For the higher level we have |
I checked 255 different combinations of optimization levels and compiler versions for division by two. The problem only exists in version 1.3.2. When the output is not simplified, it's always |
I tried adding
to the divmod function and it seems to be working fine. I realized that I was wrong and dividing by a power of 2 that is not 2 actually works out of the box. I'm looking forward to your opinion. Another finding is that my mod power 2 pattern doesn't work for the values 8 and 16 for -O0 in the test
which is quite complicated and quite an edge case. I noticed multiple weird problems there that don't happen normally, like infering u32 instead of s32 when doing division by a power of two |
Adding that to divmod makes sense to me, since it looks like a simple enough pattern that I could see coming up with other compilers/arches. I think you don't need the early_unwrap_ints(...) when comparing things to literals, literals should never have Casts around them. Also no need for
Division pattern matching is so full of them!
Yes, some of the division stuff isn't working too well with ppc, it hasn't really received all the love it deserves. |
oh, and don't you need to check that |
I will try to implement your suggestions.
I wanted to do that but they didn't match because of the sign and I wasn't sure how to cast. Will implement that too. Would you like me to later add the aforementioned mod 2 into divmod? I don't know how much of a good idea it is to implement the latter one programatically instead of an asm pattern. |
Wow, that looks awful. An asm pattern sounds good there if it works, probably for both cases. early_unwrap_ints ought to get rid of the cast and make them compare equal. |
Unfortunately the registers used in asm seem to be jambled a lot in mod by power two, I can't find a pattern that matches all cases, meanwhile the final expression seems to be consistent.
Mod 8:
Mod 16:
Mod 32:
These are the patterns I tried, but they are not universal:
|
I unfortunately don't quite get what you mean by that. |
Oh, oops, that was just wrong of me, I was thinking of the pattern wrong. I guess you just have to test both variants.
Those look reasonable to me; what goes wrong with them? |
For example if you look at the d variable, it doesn't quiet match up for all cases |
Ah, I see, I looked too hastily clearly. The pattern matching system allows multiple register variables to get assigned the same actual register, so the last pattern should be fine as long as you different destination regs for the third and fifth instructions. (With some manual guards against some registers not being equal for fuller correctness -- this is also something that IR patterns don't need. If you want to try using an IR pattern, beware that they are matched backward, so you'd need a variable for 32 - N and then use that to rewrite the other math.) |
Using MWCC 1.3.2, these operations get compiled differently (also depending on the optimization level) and don't get recognized by m2c.
On -O0,p division by 2 looks like (on -O0 it uses addze instead)
Division by power of 2 looks like
Modulo by 2 looks like
Modulo by power of 2 looks like
Is this something we want to support? If yes, do we want to do it using an assembly pattern or on a higher level? Is there a way we can add different tests for different compiler versions?
The text was updated successfully, but these errors were encountered: