-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[GlobalIsel] Cleanup G_EXTRACT_VECTOR_ELT combines #109047
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,9 +146,9 @@ bool CombinerHelper::matchExtractVectorElementWithDifferentIndices( | |
} | ||
|
||
bool CombinerHelper::matchExtractVectorElementWithBuildVector( | ||
const MachineOperand &MO, BuildFnTy &MatchInfo) { | ||
MachineInstr *Root = getDefIgnoringCopies(MO.getReg(), MRI); | ||
GExtractVectorElement *Extract = cast<GExtractVectorElement>(Root); | ||
const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) { | ||
const GExtractVectorElement *Extract = cast<GExtractVectorElement>(&MI); | ||
const GBuildVector *Build = cast<GBuildVector>(&MI2); | ||
|
||
// | ||
// %zero:_(s64) = G_CONSTANT i64 0 | ||
|
@@ -160,23 +160,8 @@ bool CombinerHelper::matchExtractVectorElementWithBuildVector( | |
// %extract:_(32) = COPY %arg1(s32) | ||
// | ||
// | ||
// | ||
// %bv:_(<2 x s32>) = G_BUILD_VECTOR %arg1(s32), %arg2(s32) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lost comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The index is never There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The case is not valid anymore. |
||
// %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %opaque(s64) | ||
// | ||
// --> | ||
// | ||
// %bv:_(<2 x s32>) = G_BUILD_VECTOR %arg1(s32), %arg2(s32) | ||
// %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %opaque(s64) | ||
// | ||
|
||
Register Vector = Extract->getVectorReg(); | ||
|
||
// We expect a buildVector on the Vector register. | ||
GBuildVector *Build = getOpcodeDef<GBuildVector>(Vector, MRI); | ||
if (!Build) | ||
return false; | ||
|
||
LLT VectorTy = MRI.getType(Vector); | ||
|
||
// There is a one-use check. There are more combines on build vectors. | ||
|
@@ -185,22 +170,15 @@ bool CombinerHelper::matchExtractVectorElementWithBuildVector( | |
!getTargetLowering().aggressivelyPreferBuildVectorSources(Ty)) | ||
return false; | ||
|
||
Register Index = Extract->getIndexReg(); | ||
|
||
// If the Index is constant, then we can extract the element from the given | ||
// offset. | ||
std::optional<ValueAndVReg> MaybeIndex = | ||
getIConstantVRegValWithLookThrough(Index, MRI); | ||
if (!MaybeIndex) | ||
return false; | ||
APInt Index = getIConstantFromReg(Extract->getIndexReg(), MRI); | ||
|
||
// We now know that there is a buildVector def'd on the Vector register and | ||
// the index is const. The combine will succeed. | ||
|
||
Register Dst = Extract->getReg(0); | ||
|
||
MatchInfo = [=](MachineIRBuilder &B) { | ||
B.buildCopy(Dst, Build->getSourceReg(MaybeIndex->Value.getZExtValue())); | ||
B.buildCopy(Dst, Build->getSourceReg(Index.getZExtValue())); | ||
}; | ||
|
||
return true; | ||
|
@@ -274,9 +252,9 @@ bool CombinerHelper::matchExtractVectorElementWithBuildVectorTrunc( | |
} | ||
|
||
bool CombinerHelper::matchExtractVectorElementWithShuffleVector( | ||
const MachineOperand &MO, BuildFnTy &MatchInfo) { | ||
GExtractVectorElement *Extract = | ||
cast<GExtractVectorElement>(getDefIgnoringCopies(MO.getReg(), MRI)); | ||
const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) { | ||
const GExtractVectorElement *Extract = cast<GExtractVectorElement>(&MI); | ||
const GShuffleVector *Shuffle = cast<GShuffleVector>(&MI2); | ||
|
||
// | ||
// %zero:_(s64) = G_CONSTANT i64 0 | ||
|
@@ -302,32 +280,12 @@ bool CombinerHelper::matchExtractVectorElementWithShuffleVector( | |
// %extract:_(s32) = G_IMPLICIT_DEF | ||
// | ||
// | ||
// | ||
// | ||
// | ||
// %sv:_(<4 x s32>) = G_SHUFFLE_SHUFFLE %arg1(<4 x s32>), %arg2(<4 x s32>), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why this comment was lost There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The case is not valid anymore. |
||
// shufflemask(0, 0, 0, -1) | ||
// %extract:_(s32) = G_EXTRACT_VECTOR_ELT %sv(<4 x s32>), %opaque(s64) | ||
// | ||
// --> | ||
// | ||
// %sv:_(<4 x s32>) = G_SHUFFLE_SHUFFLE %arg1(<4 x s32>), %arg2(<4 x s32>), | ||
// shufflemask(0, 0, 0, -1) | ||
// %extract:_(s32) = G_EXTRACT_VECTOR_ELT %sv(<4 x s32>), %opaque(s64) | ||
// | ||
|
||
// We try to get the value of the Index register. | ||
std::optional<ValueAndVReg> MaybeIndex = | ||
getIConstantVRegValWithLookThrough(Extract->getIndexReg(), MRI); | ||
if (!MaybeIndex) | ||
return false; | ||
|
||
GShuffleVector *Shuffle = | ||
cast<GShuffleVector>(getDefIgnoringCopies(Extract->getVectorReg(), MRI)); | ||
APInt Index = getIConstantFromReg(Extract->getIndexReg(), MRI); | ||
|
||
ArrayRef<int> Mask = Shuffle->getMask(); | ||
|
||
unsigned Offset = MaybeIndex->Value.getZExtValue(); | ||
unsigned Offset = Index.getZExtValue(); | ||
int SrcIdx = Mask[Offset]; | ||
|
||
LLT Src1Type = MRI.getType(Shuffle->getSrc1Reg()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -634,3 +634,30 @@ body: | | |
RET_ReallyLR implicit $x0 | ||
... | ||
--- | ||
name: extract_from_build_vector_const_huge | ||
alignment: 4 | ||
liveins: | ||
- { reg: '$x0' } | ||
- { reg: '$x1' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
body: | | ||
bb.1: | ||
liveins: $x0, $x1 | ||
; CHECK-LABEL: name: extract_from_build_vector_const_huge | ||
; CHECK: liveins: $x0, $x1 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: %arg1:_(s64) = COPY $x0 | ||
; CHECK-NEXT: $x0 = COPY %arg1(s64) | ||
; CHECK-NEXT: RET_ReallyLR implicit $x0 | ||
%vec:_(<2 x s64>) = COPY $q0 | ||
%idx:_(s64) = G_CONSTANT i64 0 | ||
%arg1:_(s64) = COPY $x0 | ||
%arg2:_(s64) = COPY $x1 | ||
%bv:_(<18 x s64>) = G_BUILD_VECTOR %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64), %arg1(s64), %arg2(s64) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The existing patterns covered up to 16. This should have been a negative test. |
||
%extract:_(s64) = G_EXTRACT_VECTOR_ELT %bv(<18 x s64>), %idx(s64) | ||
$x0 = COPY %extract(s64) | ||
RET_ReallyLR implicit $x0 | ||
|
||
... | ||
--- |
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.
Could it pass imm to avoid the need to call
getIConstantFromReg(Extract->getIndexReg(), MRI);
, or does that not work?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.
Sure everything is possible, but we would have to play with the low-level Cimm details. I would like to avoid that.