Skip to content

Commit f2c49af

Browse files
aemersonllvmbot
authored andcommitted
[AArch64][GlobalISel] Look through a G_ZEXT when trying to match shift-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)
1 parent 852f4d8 commit f2c49af

File tree

2 files changed

+61
-12
lines changed

2 files changed

+61
-12
lines changed

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4904,9 +4904,19 @@ AArch64InstructionSelector::selectExtendedSHL(
49044904
return None;
49054905

49064906
unsigned OffsetOpc = OffsetInst->getOpcode();
4907-
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
4908-
return None;
4907+
bool LookedThroughZExt = false;
4908+
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL) {
4909+
// Try to look through a ZEXT.
4910+
if (OffsetOpc != TargetOpcode::G_ZEXT || !WantsExt)
4911+
return None;
4912+
4913+
OffsetInst = MRI.getVRegDef(OffsetInst->getOperand(1).getReg());
4914+
OffsetOpc = OffsetInst->getOpcode();
4915+
LookedThroughZExt = true;
49094916

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

49584968
unsigned SignExtend = 0;
49594969
if (WantsExt) {
4960-
// Check if the offset is defined by an extend.
4961-
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
4962-
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
4963-
if (Ext == AArch64_AM::InvalidShiftExtend)
4964-
return None;
4970+
// Check if the offset is defined by an extend, unless we looked through a
4971+
// G_ZEXT earlier.
4972+
if (!LookedThroughZExt) {
4973+
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
4974+
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
4975+
if (Ext == AArch64_AM::InvalidShiftExtend)
4976+
return None;
49654977

4966-
SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
4967-
// We only support SXTW for signed extension here.
4968-
if (SignExtend && Ext != AArch64_AM::SXTW)
4969-
return None;
4978+
SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
4979+
// We only support SXTW for signed extension here.
4980+
if (SignExtend && Ext != AArch64_AM::SXTW)
4981+
return None;
4982+
OffsetReg = ExtInst->getOperand(1).getReg();
4983+
}
49704984

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

llvm/test/CodeGen/AArch64/GlobalISel/load-wro-addressing-modes.mir

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,39 @@ body: |
428428
$x1 = COPY %load(s64)
429429
RET_ReallyLR implicit $x1
430430
...
431+
---
432+
name: zext_shl_LDRWroW
433+
alignment: 4
434+
legalized: true
435+
regBankSelected: true
436+
tracksRegLiveness: true
437+
liveins:
438+
- { reg: '$w0' }
439+
- { reg: '$x1' }
440+
body: |
441+
bb.1:
442+
liveins: $w0, $x1
443+
444+
; We try to look through the G_ZEXT of the SHL here.
445+
446+
; CHECK-LABEL: name: zext_shl_LDRWroW
447+
; CHECK: liveins: $w0, $x1
448+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
449+
; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1
450+
; CHECK: [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY]], 7
451+
; CHECK: [[LDRWroW:%[0-9]+]]:gpr32 = LDRWroW [[COPY1]], [[ANDWri]], 0, 1 :: (load 4)
452+
; CHECK: $w0 = COPY [[LDRWroW]]
453+
; CHECK: RET_ReallyLR implicit $w0
454+
%0:gpr(s32) = COPY $w0
455+
%1:gpr(p0) = COPY $x1
456+
%2:gpr(s32) = G_CONSTANT i32 255
457+
%3:gpr(s32) = G_AND %0, %2
458+
%13:gpr(s64) = G_CONSTANT i64 2
459+
%12:gpr(s32) = G_SHL %3, %13(s64)
460+
%6:gpr(s64) = G_ZEXT %12(s32)
461+
%7:gpr(p0) = G_PTR_ADD %1, %6(s64)
462+
%9:gpr(s32) = G_LOAD %7(p0) :: (load 4)
463+
$w0 = COPY %9(s32)
464+
RET_ReallyLR implicit $w0
465+
466+
...

0 commit comments

Comments
 (0)