@@ -4090,9 +4090,91 @@ bool CombinerHelper::reassociationCanBreakAddressingModePattern(
40904090 return false ;
40914091}
40924092
4093- bool CombinerHelper::matchReassocPtrAdd (
4094- MachineInstr &MI, std::function<void (MachineIRBuilder &)> &MatchInfo) {
4095- assert (MI.getOpcode () == TargetOpcode::G_PTR_ADD);
4093+ bool CombinerHelper::matchReassocConstantInnerRHS (GPtrAdd &MI,
4094+ MachineInstr *RHS,
4095+ BuildFnTy &MatchInfo) {
4096+ // G_PTR_ADD(BASE, G_ADD(X, C)) -> G_PTR_ADD(G_PTR_ADD(BASE, X), C)
4097+ Register Src1Reg = MI.getOperand (1 ).getReg ();
4098+ if (RHS->getOpcode () != TargetOpcode::G_ADD)
4099+ return false ;
4100+ auto C2 = getConstantVRegVal (RHS->getOperand (2 ).getReg (), MRI);
4101+ if (!C2)
4102+ return false ;
4103+
4104+ MatchInfo = [=, &MI](MachineIRBuilder &B) {
4105+ LLT PtrTy = MRI.getType (MI.getOperand (0 ).getReg ());
4106+
4107+ auto NewBase =
4108+ Builder.buildPtrAdd (PtrTy, Src1Reg, RHS->getOperand (1 ).getReg ());
4109+ Observer.changingInstr (MI);
4110+ MI.getOperand (1 ).setReg (NewBase.getReg (0 ));
4111+ MI.getOperand (2 ).setReg (RHS->getOperand (2 ).getReg ());
4112+ Observer.changedInstr (MI);
4113+ };
4114+ return !reassociationCanBreakAddressingModePattern (MI);
4115+ }
4116+
4117+ bool CombinerHelper::matchReassocConstantInnerLHS (GPtrAdd &MI,
4118+ MachineInstr *LHS,
4119+ MachineInstr *RHS,
4120+ BuildFnTy &MatchInfo) {
4121+ // G_PTR_ADD (G_PTR_ADD X, C), Y) -> (G_PTR_ADD (G_PTR_ADD(X, Y), C)
4122+ // if and only if (G_PTR_ADD X, C) has one use.
4123+ Register LHSBase;
4124+ Register LHSCstOff;
4125+ if (!mi_match (MI.getBaseReg (), MRI,
4126+ m_OneNonDBGUse (m_GPtrAdd (m_Reg (LHSBase), m_ICst (LHSCstOff)))))
4127+ return false ;
4128+
4129+ auto *LHSPtrAdd = cast<GPtrAdd>(LHS);
4130+ MatchInfo = [=, &MI](MachineIRBuilder &B) {
4131+ // When we change LHSPtrAdd's offset register we might cause it to use a reg
4132+ // before its def. Sink the instruction so the outer PTR_ADD to ensure this
4133+ // doesn't happen.
4134+ LHSPtrAdd->moveBefore (&MI);
4135+ Register RHSReg = MI.getOffsetReg ();
4136+ Observer.changingInstr (MI);
4137+ MI.getOperand (2 ).setReg (LHSCstOff);
4138+ Observer.changedInstr (MI);
4139+ Observer.changingInstr (*LHSPtrAdd);
4140+ LHSPtrAdd->getOperand (2 ).setReg (RHSReg);
4141+ Observer.changedInstr (*LHSPtrAdd);
4142+ };
4143+ return !reassociationCanBreakAddressingModePattern (MI);
4144+ }
4145+
4146+ bool CombinerHelper::matchReassocFoldConstantsInSubTree (GPtrAdd &MI,
4147+ MachineInstr *LHS,
4148+ MachineInstr *RHS,
4149+ BuildFnTy &MatchInfo) {
4150+ // G_PTR_ADD(G_PTR_ADD(BASE, C1), C2) -> G_PTR_ADD(BASE, C1+C2)
4151+ auto *LHSPtrAdd = dyn_cast<GPtrAdd>(LHS);
4152+ if (!LHSPtrAdd)
4153+ return false ;
4154+
4155+ Register Src2Reg = MI.getOperand (2 ).getReg ();
4156+ Register LHSSrc1 = LHSPtrAdd->getBaseReg ();
4157+ Register LHSSrc2 = LHSPtrAdd->getOffsetReg ();
4158+ auto C1 = getConstantVRegVal (LHSSrc2, MRI);
4159+ if (!C1)
4160+ return false ;
4161+ auto C2 = getConstantVRegVal (Src2Reg, MRI);
4162+ if (!C2)
4163+ return false ;
4164+
4165+ MatchInfo = [=, &MI](MachineIRBuilder &B) {
4166+ auto NewCst = B.buildConstant (MRI.getType (Src2Reg), *C1 + *C2);
4167+ Observer.changingInstr (MI);
4168+ MI.getOperand (1 ).setReg (LHSSrc1);
4169+ MI.getOperand (2 ).setReg (NewCst.getReg (0 ));
4170+ Observer.changedInstr (MI);
4171+ };
4172+ return !reassociationCanBreakAddressingModePattern (MI);
4173+ }
4174+
4175+ bool CombinerHelper::matchReassocPtrAdd (MachineInstr &MI,
4176+ BuildFnTy &MatchInfo) {
4177+ auto &PtrAdd = cast<GPtrAdd>(MI);
40964178 // We're trying to match a few pointer computation patterns here for
40974179 // re-association opportunities.
40984180 // 1) Isolating a constant operand to be on the RHS, e.g.:
@@ -4101,49 +4183,26 @@ bool CombinerHelper::matchReassocPtrAdd(
41014183 // 2) Folding two constants in each sub-tree as long as such folding
41024184 // doesn't break a legal addressing mode.
41034185 // G_PTR_ADD(G_PTR_ADD(BASE, C1), C2) -> G_PTR_ADD(BASE, C1+C2)
4104- Register Src1Reg = MI.getOperand (1 ).getReg ();
4105- Register Src2Reg = MI.getOperand (2 ).getReg ();
4106- MachineInstr *LHS = MRI.getVRegDef (Src1Reg);
4107- MachineInstr *RHS = MRI.getVRegDef (Src2Reg);
4108-
4109- if (LHS->getOpcode () != TargetOpcode::G_PTR_ADD) {
4110- // Try to match example 1).
4111- if (RHS->getOpcode () != TargetOpcode::G_ADD)
4112- return false ;
4113- auto C2 = getConstantVRegVal (RHS->getOperand (2 ).getReg (), MRI);
4114- if (!C2)
4115- return false ;
4186+ //
4187+ // 3) Move a constant from the LHS of an inner op to the RHS of the outer.
4188+ // G_PTR_ADD (G_PTR_ADD X, C), Y) -> G_PTR_ADD (G_PTR_ADD(X, Y), C)
4189+ // iif (G_PTR_ADD X, C) has one use.
4190+ MachineInstr *LHS = MRI.getVRegDef (PtrAdd.getBaseReg ());
4191+ MachineInstr *RHS = MRI.getVRegDef (PtrAdd.getOffsetReg ());
4192+
4193+ // Try to match example 2.
4194+ if (matchReassocFoldConstantsInSubTree (PtrAdd, LHS, RHS, MatchInfo))
4195+ return true ;
41164196
4117- MatchInfo = [=,&MI](MachineIRBuilder &B) {
4118- LLT PtrTy = MRI.getType (MI.getOperand (0 ).getReg ());
4197+ // Try to match example 3.
4198+ if (matchReassocConstantInnerLHS (PtrAdd, LHS, RHS, MatchInfo))
4199+ return true ;
41194200
4120- auto NewBase =
4121- Builder.buildPtrAdd (PtrTy, Src1Reg, RHS->getOperand (1 ).getReg ());
4122- Observer.changingInstr (MI);
4123- MI.getOperand (1 ).setReg (NewBase.getReg (0 ));
4124- MI.getOperand (2 ).setReg (RHS->getOperand (2 ).getReg ());
4125- Observer.changedInstr (MI);
4126- };
4127- } else {
4128- // Try to match example 2.
4129- Register LHSSrc1 = LHS->getOperand (1 ).getReg ();
4130- Register LHSSrc2 = LHS->getOperand (2 ).getReg ();
4131- auto C1 = getConstantVRegVal (LHSSrc2, MRI);
4132- if (!C1)
4133- return false ;
4134- auto C2 = getConstantVRegVal (Src2Reg, MRI);
4135- if (!C2)
4136- return false ;
4201+ // Try to match example 1.
4202+ if (matchReassocConstantInnerRHS (PtrAdd, RHS, MatchInfo))
4203+ return true ;
41374204
4138- MatchInfo = [=, &MI](MachineIRBuilder &B) {
4139- auto NewCst = B.buildConstant (MRI.getType (Src2Reg), *C1 + *C2);
4140- Observer.changingInstr (MI);
4141- MI.getOperand (1 ).setReg (LHSSrc1);
4142- MI.getOperand (2 ).setReg (NewCst.getReg (0 ));
4143- Observer.changedInstr (MI);
4144- };
4145- }
4146- return !reassociationCanBreakAddressingModePattern (MI);
4205+ return false ;
41474206}
41484207
41494208bool CombinerHelper::matchConstantFold (MachineInstr &MI, APInt &MatchInfo) {
0 commit comments