Skip to content

Commit 89db3bb

Browse files
authored
[AArch64] Fix MatchDup Lane Out Of Range In AArch64 (#101275)
The original code is intended to process pattern which ISEL generated. The purpose of this pattern is duplicate a scalar value to vector register which behavior like AArch64's Dup Inst. See Url https://reviews.llvm.org/D81979 && https://reviews.llvm.org/D81221 The current code considers only the preceding situation which just duplicate from Shuffle's LHS but does not consider the user code. RHS should be considered.
1 parent 41491c7 commit 89db3bb

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,16 @@ bool matchDupFromBuildVector(int Lane, MachineInstr &MI,
288288
MachineRegisterInfo &MRI,
289289
ShuffleVectorPseudo &MatchInfo) {
290290
assert(Lane >= 0 && "Expected positive lane?");
291+
int NumElements = MRI.getType(MI.getOperand(1).getReg()).getNumElements();
291292
// Test if the LHS is a BUILD_VECTOR. If it is, then we can just reference the
292293
// lane's definition directly.
293-
auto *BuildVecMI = getOpcodeDef(TargetOpcode::G_BUILD_VECTOR,
294-
MI.getOperand(1).getReg(), MRI);
294+
auto *BuildVecMI =
295+
getOpcodeDef(TargetOpcode::G_BUILD_VECTOR,
296+
MI.getOperand(Lane < NumElements ? 1 : 2).getReg(), MRI);
297+
// If Lane >= NumElements then it is point to RHS, just check from RHS
298+
if (NumElements <= Lane)
299+
Lane -= NumElements;
300+
295301
if (!BuildVecMI)
296302
return false;
297303
Register Reg = BuildVecMI->getOperand(Lane + 1).getReg();

llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,32 @@ body: |
367367
%shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec(<4 x s32>), %undef, shufflemask(0, 0, 0, 0)
368368
$q0 = COPY %shuf(<4 x s32>)
369369
RET_ReallyLR implicit $q0
370+
371+
...
372+
---
373+
name: build_vector_rhs
374+
alignment: 4
375+
legalized: true
376+
tracksRegLiveness: true
377+
body: |
378+
bb.1.entry:
379+
liveins: $w0, $w1, $w2, $w3, $w4
380+
; The G_SHUFFLE_VECTOR is fed by a G_BUILD_VECTOR, and the 0th input
381+
; operand is not a constant. We should get a G_DUP.
382+
;
383+
; CHECK-LABEL: name: build_vector
384+
; CHECK: liveins: $w0, $w1, $w2, $w3, $w4
385+
; CHECK: %lane_1:_(s32) = COPY $w1
386+
; CHECK: %shuf:_(<4 x s32>) = G_DUP %lane_1(s32)
387+
; CHECK: $q0 = COPY %shuf(<4 x s32>)
388+
; CHECK: RET_ReallyLR implicit $q0
389+
%lane_0:_(s32) = COPY $w0
390+
%lane_1:_(s32) = COPY $w1
391+
%b:_(s32) = COPY $w2
392+
%c:_(s32) = COPY $w3
393+
%d:_(s32) = COPY $w4
394+
%buildvec0:_(<4 x s32>) = G_BUILD_VECTOR %lane_0(s32), %b(s32), %c(s32), %d(s32)
395+
%buildvec1:_(<4 x s32>) = G_BUILD_VECTOR %lane_1(s32), %b(s32), %c(s32), %d(s32)
396+
%shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x s32>), %buildvec1, shufflemask(4, 4, 4, 4)
397+
$q0 = COPY %shuf(<4 x s32>)
398+
RET_ReallyLR implicit $q0

0 commit comments

Comments
 (0)