The SDAG will sometimes insert an extend between the shift and an and (immediate) even though the immediate is narrower than the narrow size. This does not allow us to produce a rotate instruction (such as rlwinm).
This patch just adds a combine to move the extend onto the and.
Details
- Reviewers
qiongsiwu stefanp lei amyk - Group Reviewers
Restricted Project - Commits
- rGa57236de4eb8: [PowerPC] Remove extend between shift and and
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
LGTM.
llvm/test/CodeGen/PowerPC/and-extend-combine.ll | ||
---|---|---|
3 | Is an AIX run line also necessary? |
This patch makes sense to me. I just had one nit and one idea.
edit:
Sorry, I'm being difficult. :)
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | ||
---|---|---|
15505 | It may be possible to also make this safe for sign extend. if(Imm >= maxUIntN(NarrowVT.getSizeInBits())) break; to check if the immediate fits in the not yet extended range. if (Op1.getOpcode() == ISD::SIGN_EXTEND && Imm >= maxUIntN(NarrowVT.getSizeInBits() - 1)) break; When you subtract 1 from the range you know that the sign bit on whatever we extend is going to be zero (because it is for the constant and we are doing an AND) so the sign extend becomes a zero extend and everything is fine. I'm not 100% about this idea but it might work. | |
15512 | nit: NarrowOp.getOpcode() is used a lot in this if statement. You may want to pull it out. unsigned NarrowOpcode = NarrowOp.getOpcode(); if (NarrowOpcode != ISD::SHL && ... |
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | ||
---|---|---|
15505 | I think this may be correct, but I can't envision a situation where we sign-extend a value and then AND it with a narrower value. The SDAG should always convert such "don't care" extends to ANY_EXTENDs. | |
15512 | Makes sense. Not sure why I didn't do this. | |
llvm/test/CodeGen/PowerPC/and-extend-combine.ll | ||
3 | I don't think there is anything to be gained by adding it. The code is completely independent of the platform or even subtarget. |
I think this patch looks good.
I'm going to approve it and the nit that I had:
unsigned NarrowOpcode = NarrowOp.getOpcode(); if (NarrowOpcode != ISD::SHL && ...
can be addressed on commit.
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | ||
---|---|---|
15505 | Fair enough. Don't worry about it! |
It may be possible to also make this safe for sign extend.
At this point you are using
to check if the immediate fits in the not yet extended range.
In the SIGN_EXTEND case you can do this by using
When you subtract 1 from the range you know that the sign bit on whatever we extend is going to be zero (because it is for the constant and we are doing an AND) so the sign extend becomes a zero extend and everything is fine.
I'm not 100% about this idea but it might work.