-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[AArch64][GlobalISel] Add lowering for constant BIT/BIF/BSP #65897
Conversation
@@ -216,7 +216,7 @@ def G_PREFETCH : AArch64GenericInstruction { | |||
} | |||
|
|||
// Generic bitwise insert if true. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment needs updating.
@@ -216,7 +216,7 @@ def G_PREFETCH : AArch64GenericInstruction { | |||
} | |||
|
|||
// Generic bitwise insert if true. | |||
def G_BIT : AArch64GenericInstruction { | |||
def G_BSP : AArch64GenericInstruction { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this opcode needs a bit of documentation since it's not a real AArch64 instruction.
MachineInstr *LHS = | ||
getOpcodeDef(TargetOpcode::G_AND, MI.getOperand(1).getReg(), MRI); | ||
MachineInstr *RHS = | ||
getOpcodeDef(TargetOpcode::G_AND, MI.getOperand(2).getReg(), MRI); | ||
if (!LHS || !RHS) | ||
return false; | ||
|
||
auto *BV1 = getOpcodeDef<GBuildVector>(LHS->getOperand(2).getReg(), MRI); | ||
auto *BV2 = getOpcodeDef<GBuildVector>(RHS->getOperand(2).getReg(), MRI); | ||
if (!BV1 || !BV2) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least some of this could be done with mi_match()
? Not a big deal either way.
std::get<0>(MatchInfo) = LHS->getOperand(1).getReg(); | ||
std::get<1>(MatchInfo) = RHS->getOperand(1).getReg(); | ||
std::get<2>(MatchInfo) = RHS->getOperand(2).getReg(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just do MatchInfo = {v1,v2,v3};
for (int k = 0; k < DstTy.getNumElements(); k++) { | ||
auto ValAndVReg1 = getIConstantVRegValWithLookThrough( | ||
BV1->getOperand(k + 1).getReg(), MRI); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use GBuildVector::getSourceReg(k)
.
auto ValAndVReg2 = getIConstantVRegValWithLookThrough( | ||
BV2->getOperand(k + 1).getReg(), MRI); | ||
if (!ValAndVReg1 || !ValAndVReg2 || | ||
ValAndVReg1->Value != ~ValAndVReg2->Value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer *ValAndReg1
for ValAndReg2
precedence is not obvious.
if (!BV1 || !BV2) | ||
return false; | ||
|
||
for (int k = 0; k < DstTy.getNumElements(); k++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (int k = 0, int NumElements = DstTy.getNumElements(); k < NumElements; ++k)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the far future a scalable vector might sneak in, then you cannot walk over its members.
The non-constant versions already work through tablegen patters, this mirrors the basic support for or(and(X, C), and(Y, ~C)) from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
2df1802
to
ff25643
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Hi @davemgreen, I am seeing flang/clang failures in the llvm-test-suite after this patch with tests involving copy sign:
Can you check if this is related to your patch that involves copy sign on aarch64? |
Hello. It sounds like it might be related. I might not have updated the existing copysign code correctly, as I was planning to remove it eventually. I will revert and take a look. |
The non-constant bit/bif/bsp already work through tablegen patterns, this patch handles the constant case, mirroring the basic support for `or(and(X, C), and(Y, ~C))` from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
The non-constant bit/bif/bsp already work through tablegen patterns, this patch handles the constant case, mirroring the basic support for `or(and(X, C), and(Y, ~C))` from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
The non-constant bit/bif/bsp already work through tablegen patterns, this patch handles the constant case, mirroring the basic support for `or(and(X, C), and(Y, ~C))` from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
The non-constant bit/bif/bsp already work through tablegen patterns, this patch handles the constant case, mirroring the basic support for `or(and(X, C), and(Y, ~C))` from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
The non-constant bit/bif/bsp already work through tablegen patterns, this patch handles the constant case, mirroring the basic support for `or(and(X, C), and(Y, ~C))` from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.
I have been making my way through GlobalISel vector fp, making sure all the basic types are currently working. In looking at fcopysign I managed to rewrite it in a way that we just widen to vectors, as opposed to relying on custom lowering. That misses handling vector constants (which Mark here is currently looking at) and transforming
or
/and
intobit
.The non-constant bit/bif/bsp already work through tablegen patters, this patch handles the constant case, mirroring the basic support for
or(and(X, C), and(Y, ~C))
from ISel tryCombineToBSL. BSP gets expanded to either BIT, BIF or BSL depending on the best register allocation. G_BIT can be replaced with G_BSP as a more general alternative.