Skip to content

Commit

Permalink
[AArch64][GlobalISel] Look through a G_ZEXT when trying to match shif…
Browse files Browse the repository at this point in the history
…t-extended register offsets.

The G_ZEXT in these cases seems to actually come from a combine that we do but
SelectionDAG doesn't. Looking through it allows us to match "uxtw #2" addressing
modes.

Differential Revision: https://reviews.llvm.org/D91475

(cherry picked from commit 0b60906)
  • Loading branch information
aemerson authored and tstellar committed Dec 15, 2020
1 parent 6ec777c commit 9e16c5b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 12 deletions.
37 changes: 25 additions & 12 deletions llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4904,9 +4904,19 @@ AArch64InstructionSelector::selectExtendedSHL(
return None;

unsigned OffsetOpc = OffsetInst->getOpcode();
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
return None;
bool LookedThroughZExt = false;
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL) {
// Try to look through a ZEXT.
if (OffsetOpc != TargetOpcode::G_ZEXT || !WantsExt)
return None;

OffsetInst = MRI.getVRegDef(OffsetInst->getOperand(1).getReg());
OffsetOpc = OffsetInst->getOpcode();
LookedThroughZExt = true;

if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
return None;
}
// Make sure that the memory op is a valid size.
int64_t LegalShiftVal = Log2_32(SizeInBytes);
if (LegalShiftVal == 0)
Expand Down Expand Up @@ -4957,20 +4967,23 @@ AArch64InstructionSelector::selectExtendedSHL(

unsigned SignExtend = 0;
if (WantsExt) {
// Check if the offset is defined by an extend.
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
if (Ext == AArch64_AM::InvalidShiftExtend)
return None;
// Check if the offset is defined by an extend, unless we looked through a
// G_ZEXT earlier.
if (!LookedThroughZExt) {
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
if (Ext == AArch64_AM::InvalidShiftExtend)
return None;

SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
// We only support SXTW for signed extension here.
if (SignExtend && Ext != AArch64_AM::SXTW)
return None;
SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
// We only support SXTW for signed extension here.
if (SignExtend && Ext != AArch64_AM::SXTW)
return None;
OffsetReg = ExtInst->getOperand(1).getReg();
}

// Need a 32-bit wide register here.
MachineIRBuilder MIB(*MRI.getVRegDef(Root.getReg()));
OffsetReg = ExtInst->getOperand(1).getReg();
OffsetReg = narrowExtendRegIfNeeded(OffsetReg, MIB);
}

Expand Down
36 changes: 36 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/load-wro-addressing-modes.mir
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,39 @@ body: |
$x1 = COPY %load(s64)
RET_ReallyLR implicit $x1
...
---
name: zext_shl_LDRWroW
alignment: 4
legalized: true
regBankSelected: true
tracksRegLiveness: true
liveins:
- { reg: '$w0' }
- { reg: '$x1' }
body: |
bb.1:
liveins: $w0, $x1
; We try to look through the G_ZEXT of the SHL here.
; CHECK-LABEL: name: zext_shl_LDRWroW
; CHECK: liveins: $w0, $x1
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1
; CHECK: [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY]], 7
; CHECK: [[LDRWroW:%[0-9]+]]:gpr32 = LDRWroW [[COPY1]], [[ANDWri]], 0, 1 :: (load 4)
; CHECK: $w0 = COPY [[LDRWroW]]
; CHECK: RET_ReallyLR implicit $w0
%0:gpr(s32) = COPY $w0
%1:gpr(p0) = COPY $x1
%2:gpr(s32) = G_CONSTANT i32 255
%3:gpr(s32) = G_AND %0, %2
%13:gpr(s64) = G_CONSTANT i64 2
%12:gpr(s32) = G_SHL %3, %13(s64)
%6:gpr(s64) = G_ZEXT %12(s32)
%7:gpr(p0) = G_PTR_ADD %1, %6(s64)
%9:gpr(s32) = G_LOAD %7(p0) :: (load 4)
$w0 = COPY %9(s32)
RET_ReallyLR implicit $w0
...

0 comments on commit 9e16c5b

Please sign in to comment.