@@ -7062,6 +7062,42 @@ bool CombinerHelper::matchSelectIMinMax(const MachineOperand &MO,
70627062 }
70637063}
70647064
7065+ // (neg (min/max x, (neg x))) --> (max/min x, (neg x))
7066+ bool CombinerHelper::matchSimplifyNegMinMax (MachineInstr &MI,
7067+ BuildFnTy &MatchInfo) const {
7068+ assert (MI.getOpcode () == TargetOpcode::G_SUB);
7069+ Register DestReg = MI.getOperand (0 ).getReg ();
7070+ LLT DestTy = MRI.getType (DestReg);
7071+ if (!isLegal ({TargetOpcode::G_SUB, {DestTy}}))
7072+ return false ;
7073+
7074+ // GISel doesn't have m_Deferred at this moment, so we have to
7075+ // match this pattern in two phases.
7076+ Register X, Y;
7077+ Register Sub0;
7078+ if (mi_match (DestReg, MRI,
7079+ m_Neg (m_OneUse (m_any_of (
7080+ m_GSMin (m_Reg (X), m_Reg (Y)), m_GSMax (m_Reg (X), m_Reg (Y)),
7081+ m_CommutativeBinOp (TargetOpcode::G_UMIN, m_Reg (X), m_Reg (Y)),
7082+ m_CommutativeBinOp (TargetOpcode::G_UMAX, m_Reg (X),
7083+ m_Reg (Y)))))) &&
7084+ (mi_match (Y, MRI, m_all_of (m_Neg (m_SpecificReg (X)), m_Reg (Sub0))) ||
7085+ mi_match (X, MRI, m_all_of (m_Neg (m_SpecificReg (Y)), m_Reg (Sub0))))) {
7086+ MachineInstr *MinMaxMI = MRI.getVRegDef (MI.getOperand (2 ).getReg ());
7087+ MachineInstr *Sub0MI = MRI.getVRegDef (Sub0);
7088+ X = Sub0MI->getOperand (2 ).getReg ();
7089+ unsigned NewOpc = getInverseGMinMaxOpcode (MinMaxMI->getOpcode ());
7090+ if (isLegal ({NewOpc, {DestTy}})) {
7091+ MatchInfo = [=](MachineIRBuilder &B) {
7092+ B.buildInstr (NewOpc, {DestReg}, {X, Sub0});
7093+ };
7094+ return true ;
7095+ }
7096+ }
7097+
7098+ return false ;
7099+ }
7100+
70657101bool CombinerHelper::matchSelect (MachineInstr &MI, BuildFnTy &MatchInfo) const {
70667102 GSelect *Select = cast<GSelect>(&MI);
70677103
0 commit comments