@@ -3417,10 +3417,10 @@ static void changeLoadStoreDataRegister(MachineInstr &MI, Register DataReg,
34173417}
34183418
34193419// / Narrow operations that are feeding truncations to s20.
3420- // / Covers G_LOAD and G_CONSTANT.
3421- bool llvm::matchNarrowTrunc (MachineInstr &MI , MachineRegisterInfo &MRI ,
3422- GISelChangeObserver &Observer,
3423- BuildFnTy &MatchInfo) {
3420+ // / Covers G_CONSTANT.
3421+ bool llvm::matchNarrowTruncConstant (MachineInstr &MI , MachineRegisterInfo &MRI ,
3422+ GISelChangeObserver &Observer,
3423+ BuildFnTy &MatchInfo) {
34243424
34253425 assert (MI .getOpcode () == TargetOpcode::G_TRUNC );
34263426
@@ -3431,38 +3431,59 @@ bool llvm::matchNarrowTrunc(MachineInstr &MI, MachineRegisterInfo &MRI,
34313431
34323432 MachineInstr &SrcMI = *MRI .getVRegDef (SrcReg);
34333433
3434- if (SrcMI.getOpcode () == TargetOpcode::G_CONSTANT ) {
3435- MatchInfo = [=, &MI , &SrcMI, &MRI , &Observer](MachineIRBuilder &B) {
3436- auto NewConstant = B.buildConstant (
3437- LLT::scalar (20 ),
3438- *getIConstantVRegSExtVal (SrcMI.getOperand (0 ).getReg (), MRI ));
3439- Register FromReg = MI .getOperand (0 ).getReg ();
3440- Observer.changingAllUsesOfReg (MRI , FromReg);
3441- MRI .replaceRegWith (FromReg, NewConstant->getOperand (0 ).getReg ());
3442- Observer.finishedChangingAllUsesOfReg ();
3443- MI .eraseFromParent ();
3444- };
3445- return true ;
3446- }
3434+ if (SrcMI.getOpcode () != TargetOpcode::G_CONSTANT )
3435+ return false ;
3436+
3437+ MatchInfo = [=, &MI , &SrcMI, &MRI , &Observer](MachineIRBuilder &B) {
3438+ auto NewConstant = B.buildConstant (
3439+ LLT::scalar (20 ),
3440+ *getIConstantVRegSExtVal (SrcMI.getOperand (0 ).getReg (), MRI ));
3441+ Register FromReg = MI .getOperand (0 ).getReg ();
3442+ Observer.changingAllUsesOfReg (MRI , FromReg);
3443+ MRI .replaceRegWith (FromReg, NewConstant->getOperand (0 ).getReg ());
3444+ Observer.finishedChangingAllUsesOfReg ();
3445+ MI .eraseFromParent ();
3446+ };
3447+
3448+ return true ;
3449+ }
3450+
3451+ // / Narrow operations that are feeding truncations to s20.
3452+ // / Covers G_LOAD.
3453+ bool llvm::matchNarrowTruncLoad (MachineInstr &MI , MachineRegisterInfo &MRI ,
3454+ CombinerHelper &Helper,
3455+ GISelChangeObserver &Observer,
3456+ BuildFnTy &MatchInfo) {
34473457
3448- // Ideally, we could allow more users, provided that they are all TRUNCs.
3449- // However, if we have more users, the live range of this register could
3450- // spread through more blocks, and this could lead to more register pressure
3451- // on s20 registers.
3452- if (!MRI .hasOneNonDBGUse (SrcReg) || !isUsedByLikelyLegalS20User (MRI , MI ))
3458+ assert (MI .getOpcode () == TargetOpcode::G_LOAD );
3459+
3460+ const LLT S20 = LLT::scalar (20 );
3461+ auto IsProfitableTruncToS20 = [&](const MachineInstr &MaybeTruncMI) {
3462+ if (MaybeTruncMI.getOpcode () != TargetOpcode::G_TRUNC )
3463+ return false ;
3464+ const Register DstReg = MaybeTruncMI.getOperand (0 ).getReg ();
3465+ if (MRI .getType (DstReg) != S20 )
3466+ return false ;
3467+ return isUsedByLikelyLegalS20User (MRI , MaybeTruncMI);
3468+ };
3469+
3470+ // We should have a G_LOAD feeding interesting truncations.
3471+ const Register DstReg = MI .getOperand (0 ).getReg ();
3472+ if (!all_of (MRI .use_instructions (DstReg), IsProfitableTruncToS20))
34533473 return false ;
34543474
3455- if (SrcMI.getOpcode () == TargetOpcode::G_LOAD ) {
3456- MatchInfo = [=, &MI , &SrcMI, &MRI , &Observer](MachineIRBuilder &B) {
3457- Observer.changingInstr (SrcMI);
3458- changeLoadStoreDataRegister (SrcMI, MI .getOperand (0 ).getReg (), MRI );
3459- Observer.changedInstr (SrcMI);
3460- MI .eraseFromParent ();
3461- };
3462- return true ;
3463- }
3475+ MatchInfo = [=, &MI , &MRI , &Observer](MachineIRBuilder &B) {
3476+ const Register NewDstReg = MRI .createGenericVirtualRegister (S20 );
3477+ Observer.changingInstr (MI );
3478+ changeLoadStoreDataRegister (MI , NewDstReg, MRI );
3479+ Observer.changedInstr (MI );
3480+ // Build Zext after the load, not before.
3481+ MachineBasicBlock &MBB = *MI .getParent ();
3482+ B.setInsertPt (MBB , MI .getNextNode () ? MI .getNextNode () : MBB .end ());
3483+ Observer.createdInstr (*B.buildZExt (DstReg, NewDstReg));
3484+ };
34643485
3465- return false ;
3486+ return true ;
34663487}
34673488
34683489// / Narrow operations that are fed by zext from s20.
0 commit comments