When a comparison is extended and it would be free to extend the
arguments to that comparison, we can propagate the extend into those arguments.
This prevents extra instructions being generated to extend the result of the
comparison, which is not free to extend.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
Looks reasonable to me. A suggestion inline.
One other request, please could we have a brief comment or lispy expression on the function which does the combine to indicate why it exists / what the intent is.
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
15298 | I see you've protected N->getOperand(0) with this assert, but what about N->getOpcode()? I would like to see a structure that looks a bit more like performORCombine, for example which looks like the below. That would pull the conditions into this function and make this assert into a if (!...) return SDValue() instead. The motivation behind my ask is to put all the logic for this combine in this function. static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget) { //... if (SDValue Res = tryCombineToEXTR(N, DCI)) return Res; ... } static SDValue tryCombineToEXTR(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) { assert(N->getOpcode() == ISD::OR && "Unexpected root"); // ... } |
Expand assert to protect N->getOpcode()
Add comment to combine to explain its purpose
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
15298 | I wrote it this way following some of the other functions in this file, it doesn't seem there's much consistency between this way and they way you're suggesting! My gut instinct tells me it's clearer in this case to have the condition in the other function and the assertion here, because then it shows clearly in which circumstances you're going to call this combine. I'm happy to change it if you think it would be better the other way around though! |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
15292 | I see tests hitting the MLOAD case, but not the LOAD nor isConstantSplatVectorAllZeros cases. Any thoughts on that? Another idea that pops into mind: I might expect that all constants could be cheap to extend, as logically they can be rewritten as another constant. I see that FoldConstantArithmetic might achieve this in getNode for the SIGN_EXTEND. Not necessarily for this patch unless you agree and think it's easy to do. | |
15298 | I agree there are different ways this is written, the above comment is only a suggestion so I'm happy to proceed as is. |
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
15292 |
Thanks for pointing out to me offline that the test cases do hit these (of course!). |
Hi @DavidTruby, this patch causes a build failure on MultiSource/Applications/JM/lencod (file rc_quadratic.c) when enabling SVE. Can you please investigate and revert/fix?
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | ||
---|---|---|
15310–15313 | This doesn't look correct. The extension type should mirror the comparison operator. So whilst signed comparisons require the original operands to be sign-extended, unsigned comparisons will require the operands to be zero extended to match the original behaviour. |
I see tests hitting the MLOAD case, but not the LOAD nor isConstantSplatVectorAllZeros cases. Any thoughts on that?
Another idea that pops into mind: I might expect that all constants could be cheap to extend, as logically they can be rewritten as another constant. I see that FoldConstantArithmetic might achieve this in getNode for the SIGN_EXTEND. Not necessarily for this patch unless you agree and think it's easy to do.