@@ -289,14 +289,15 @@ class AArch64InstructionSelector : public InstructionSelector {
289
289
getExtendTypeForInst (MachineInstr &MI, MachineRegisterInfo &MRI,
290
290
bool IsLoadStore = false ) const ;
291
291
292
- // / Instructions that accept extend modifiers like UXTW expect the register
293
- // / being extended to be a GPR32. Narrow ExtReg to a 32-bit register using a
294
- // / subregister copy if necessary. Return either ExtReg, or the result of the
295
- // / new copy.
296
- Register narrowExtendRegIfNeeded (Register ExtReg,
297
- MachineIRBuilder &MIB) const ;
298
- Register widenGPRBankRegIfNeeded (Register Reg, unsigned Size,
299
- MachineIRBuilder &MIB) const ;
292
+ // / Move \p Reg to \p RC if \p Reg is not already on \p RC.
293
+ // /
294
+ // / \returns Either \p Reg if no change was necessary, or the new register
295
+ // / created by moving \p Reg.
296
+ // /
297
+ // / Note: This uses emitCopy right now.
298
+ Register moveScalarRegClass (Register Reg, const TargetRegisterClass &RC,
299
+ MachineIRBuilder &MIB) const ;
300
+
300
301
ComplexRendererFns selectArithExtendedRegister (MachineOperand &Root) const ;
301
302
302
303
void renderTruncImm (MachineInstrBuilder &MIB, const MachineInstr &MI,
@@ -1195,10 +1196,10 @@ MachineInstr *AArch64InstructionSelector::emitTestBit(
1195
1196
// TBNZW work.
1196
1197
bool UseWReg = Bit < 32 ;
1197
1198
unsigned NecessarySize = UseWReg ? 32 : 64 ;
1198
- if (Size < NecessarySize)
1199
- TestReg = widenGPRBankRegIfNeeded (TestReg, NecessarySize, MIB);
1200
- else if (Size > NecessarySize)
1201
- TestReg = narrowExtendRegIfNeeded (TestReg, MIB);
1199
+ if (Size != NecessarySize)
1200
+ TestReg = moveScalarRegClass (
1201
+ TestReg, UseWReg ? AArch64::GPR32RegClass : AArch64::GPR64RegClass,
1202
+ MIB);
1202
1203
1203
1204
static const unsigned OpcTable[2 ][2 ] = {{AArch64::TBZX, AArch64::TBNZX},
1204
1205
{AArch64::TBZW, AArch64::TBNZW}};
@@ -4907,9 +4908,19 @@ AArch64InstructionSelector::selectExtendedSHL(
4907
4908
return None;
4908
4909
4909
4910
unsigned OffsetOpc = OffsetInst->getOpcode ();
4910
- if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
4911
- return None;
4911
+ bool LookedThroughZExt = false ;
4912
+ if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL) {
4913
+ // Try to look through a ZEXT.
4914
+ if (OffsetOpc != TargetOpcode::G_ZEXT || !WantsExt)
4915
+ return None;
4916
+
4917
+ OffsetInst = MRI.getVRegDef (OffsetInst->getOperand (1 ).getReg ());
4918
+ OffsetOpc = OffsetInst->getOpcode ();
4919
+ LookedThroughZExt = true ;
4912
4920
4921
+ if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
4922
+ return None;
4923
+ }
4913
4924
// Make sure that the memory op is a valid size.
4914
4925
int64_t LegalShiftVal = Log2_32 (SizeInBytes);
4915
4926
if (LegalShiftVal == 0 )
@@ -4960,21 +4971,24 @@ AArch64InstructionSelector::selectExtendedSHL(
4960
4971
4961
4972
unsigned SignExtend = 0 ;
4962
4973
if (WantsExt) {
4963
- // Check if the offset is defined by an extend.
4964
- MachineInstr *ExtInst = getDefIgnoringCopies (OffsetReg, MRI);
4965
- auto Ext = getExtendTypeForInst (*ExtInst, MRI, true );
4966
- if (Ext == AArch64_AM::InvalidShiftExtend)
4967
- return None;
4974
+ // Check if the offset is defined by an extend, unless we looked through a
4975
+ // G_ZEXT earlier.
4976
+ if (!LookedThroughZExt) {
4977
+ MachineInstr *ExtInst = getDefIgnoringCopies (OffsetReg, MRI);
4978
+ auto Ext = getExtendTypeForInst (*ExtInst, MRI, true );
4979
+ if (Ext == AArch64_AM::InvalidShiftExtend)
4980
+ return None;
4968
4981
4969
- SignExtend = isSignExtendShiftType (Ext) ? 1 : 0 ;
4970
- // We only support SXTW for signed extension here.
4971
- if (SignExtend && Ext != AArch64_AM::SXTW)
4972
- return None;
4982
+ SignExtend = isSignExtendShiftType (Ext) ? 1 : 0 ;
4983
+ // We only support SXTW for signed extension here.
4984
+ if (SignExtend && Ext != AArch64_AM::SXTW)
4985
+ return None;
4986
+ OffsetReg = ExtInst->getOperand (1 ).getReg ();
4987
+ }
4973
4988
4974
4989
// Need a 32-bit wide register here.
4975
4990
MachineIRBuilder MIB (*MRI.getVRegDef (Root.getReg ()));
4976
- OffsetReg = ExtInst->getOperand (1 ).getReg ();
4977
- OffsetReg = narrowExtendRegIfNeeded (OffsetReg, MIB);
4991
+ OffsetReg = moveScalarRegClass (OffsetReg, AArch64::GPR32RegClass, MIB);
4978
4992
}
4979
4993
4980
4994
// We can use the LHS of the GEP as the base, and the LHS of the shift as an
@@ -5146,8 +5160,8 @@ AArch64InstructionSelector::selectAddrModeWRO(MachineOperand &Root,
5146
5160
5147
5161
// Need a 32-bit wide register.
5148
5162
MachineIRBuilder MIB (*PtrAdd);
5149
- Register ExtReg =
5150
- narrowExtendRegIfNeeded (OffsetInst-> getOperand ( 1 ). getReg () , MIB);
5163
+ Register ExtReg = moveScalarRegClass (OffsetInst-> getOperand ( 1 ). getReg (),
5164
+ AArch64::GPR32RegClass , MIB);
5151
5165
unsigned SignExtend = Ext == AArch64_AM::SXTW;
5152
5166
5153
5167
// Base is LHS, offset is ExtReg.
@@ -5421,67 +5435,21 @@ AArch64_AM::ShiftExtendType AArch64InstructionSelector::getExtendTypeForInst(
5421
5435
}
5422
5436
}
5423
5437
5424
- Register AArch64InstructionSelector::narrowExtendRegIfNeeded (
5425
- Register ExtReg , MachineIRBuilder &MIB) const {
5438
+ Register AArch64InstructionSelector::moveScalarRegClass (
5439
+ Register Reg, const TargetRegisterClass &RC , MachineIRBuilder &MIB) const {
5426
5440
MachineRegisterInfo &MRI = *MIB.getMRI ();
5427
- if (MRI.getType (ExtReg).getSizeInBits () == 32 )
5428
- return ExtReg;
5429
-
5430
- // Insert a copy to move ExtReg to GPR32.
5431
- Register NarrowReg = MRI.createVirtualRegister (&AArch64::GPR32RegClass);
5432
- auto Copy = MIB.buildCopy ({NarrowReg}, {ExtReg});
5441
+ auto Ty = MRI.getType (Reg);
5442
+ assert (!Ty.isVector () && " Expected scalars only!" );
5443
+ if (Ty.getSizeInBits () == TRI.getRegSizeInBits (RC))
5444
+ return Reg;
5433
5445
5434
- // Select the copy into a subregister copy.
5446
+ // Create a copy and immediately select it.
5447
+ // FIXME: We should have an emitCopy function?
5448
+ auto Copy = MIB.buildCopy ({&RC}, {Reg});
5435
5449
selectCopy (*Copy, TII, MRI, TRI, RBI);
5436
5450
return Copy.getReg (0 );
5437
5451
}
5438
5452
5439
- Register AArch64InstructionSelector::widenGPRBankRegIfNeeded (
5440
- Register Reg, unsigned WideSize, MachineIRBuilder &MIB) const {
5441
- assert (WideSize >= 8 && " WideSize is smaller than all possible registers?" );
5442
- MachineRegisterInfo &MRI = *MIB.getMRI ();
5443
- unsigned NarrowSize = MRI.getType (Reg).getSizeInBits ();
5444
- assert (WideSize >= NarrowSize &&
5445
- " WideSize cannot be smaller than NarrowSize!" );
5446
-
5447
- // If the sizes match, just return the register.
5448
- //
5449
- // If NarrowSize is an s1, then we can select it to any size, so we'll treat
5450
- // it as a don't care.
5451
- if (NarrowSize == WideSize || NarrowSize == 1 )
5452
- return Reg;
5453
-
5454
- // Now check the register classes.
5455
- const RegisterBank *RB = RBI.getRegBank (Reg, MRI, TRI);
5456
- const TargetRegisterClass *OrigRC = getMinClassForRegBank (*RB, NarrowSize);
5457
- const TargetRegisterClass *WideRC = getMinClassForRegBank (*RB, WideSize);
5458
- assert (OrigRC && " Could not determine narrow RC?" );
5459
- assert (WideRC && " Could not determine wide RC?" );
5460
-
5461
- // If the sizes differ, but the register classes are the same, there is no
5462
- // need to insert a SUBREG_TO_REG.
5463
- //
5464
- // For example, an s8 that's supposed to be a GPR will be selected to either
5465
- // a GPR32 or a GPR64 register. Note that this assumes that the s8 will
5466
- // always end up on a GPR32.
5467
- if (OrigRC == WideRC)
5468
- return Reg;
5469
-
5470
- // We have two different register classes. Insert a SUBREG_TO_REG.
5471
- unsigned SubReg = 0 ;
5472
- getSubRegForClass (OrigRC, TRI, SubReg);
5473
- assert (SubReg && " Couldn't determine subregister?" );
5474
-
5475
- // Build the SUBREG_TO_REG and return the new, widened register.
5476
- auto SubRegToReg =
5477
- MIB.buildInstr (AArch64::SUBREG_TO_REG, {WideRC}, {})
5478
- .addImm (0 )
5479
- .addUse (Reg)
5480
- .addImm (SubReg);
5481
- constrainSelectedInstRegOperands (*SubRegToReg, TII, TRI, RBI);
5482
- return SubRegToReg.getReg (0 );
5483
- }
5484
-
5485
5453
// / Select an "extended register" operand. This operand folds in an extend
5486
5454
// / followed by an optional left shift.
5487
5455
InstructionSelector::ComplexRendererFns
@@ -5542,7 +5510,7 @@ AArch64InstructionSelector::selectArithExtendedRegister(
5542
5510
// We require a GPR32 here. Narrow the ExtReg if needed using a subregister
5543
5511
// copy.
5544
5512
MachineIRBuilder MIB (*RootDef);
5545
- ExtReg = narrowExtendRegIfNeeded (ExtReg, MIB);
5513
+ ExtReg = moveScalarRegClass (ExtReg, AArch64::GPR32RegClass , MIB);
5546
5514
5547
5515
return {{[=](MachineInstrBuilder &MIB) { MIB.addUse (ExtReg); },
5548
5516
[=](MachineInstrBuilder &MIB) {
0 commit comments