[llvm] [GlobalIsel] Combine G_ADD and G_SUB with constants (PR #97771)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 19 00:40:34 PDT 2024
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>,
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/97771 at github.com>
================
@@ -7490,3 +7490,153 @@ bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
return false;
}
+
+bool CombinerHelper::matchFoldAPlusC1MinusC2(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ // fold (A+C1)-C2 -> A+(C1-C2)
+ const GSub *Sub = cast<GSub>(&MI);
+ GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getLHSReg()));
+
+ if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub->getRHSReg(), MRI);
+ if (!MaybeC2)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC1 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+ if (!MaybeC1)
+ return false;
+
+ Register Dst = Sub->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Const = B.buildConstant(DstTy, *MaybeC1 - *MaybeC2);
+ B.buildAdd(Dst, Add->getLHSReg(), Const);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchFoldC2MinusAPlusC1(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ // fold C2-(A+C1) -> (C2-C1)-A
+ const GSub *Sub = cast<GSub>(&MI);
+ GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getRHSReg()));
+
+ if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub->getLHSReg(), MRI);
+ if (!MaybeC2)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC1 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+ if (!MaybeC1)
+ return false;
+
+ Register Dst = Sub->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Const = B.buildConstant(DstTy, *MaybeC2 - *MaybeC1);
+ B.buildSub(Dst, Const, Add->getLHSReg());
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchFoldAMinusC1MinusC2(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ // fold (A-C1)-C2 -> A-(C1+C2)
+ const GSub *Sub1 = cast<GSub>(&MI);
+ GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+
+ if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub1->getRHSReg(), MRI);
+ if (!MaybeC2)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub2->getRHSReg(), MRI);
+ if (!MaybeC1)
+ return false;
+
+ Register Dst = Sub1->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Const = B.buildConstant(DstTy, *MaybeC1 + *MaybeC2);
+ B.buildSub(Dst, Sub2->getLHSReg(), Const);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchFoldC1Minus2MinusC2(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ // fold (C1-A)-C2 -> (C1-C2)-A
+ const GSub *Sub1 = cast<GSub>(&MI);
+ GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+
+ if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub1->getRHSReg(), MRI);
+ if (!MaybeC2)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub2->getLHSReg(), MRI);
+ if (!MaybeC1)
+ return false;
+
+ Register Dst = Sub1->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Const = B.buildConstant(DstTy, *MaybeC1 - *MaybeC2);
+ B.buildSub(Dst, Const, Sub2->getRHSReg());
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchFoldAMinusC2PlusC2(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ // fold ((A-C1)+C2) -> (A+(C2-C1))
+ const GAdd *Add = cast<GAdd>(&MI);
+ GSub *Sub = cast<GSub>(MRI.getVRegDef(Add->getLHSReg()));
+
+ if (!MRI.hasOneNonDBGUse(Sub->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC2 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+ if (!MaybeC2)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub->getRHSReg(), MRI);
+ if (!MaybeC1)
+ return false;
----------------
arsenm wrote:
Ditto
https://github.com/llvm/llvm-project/pull/97771
More information about the llvm-commits
mailing list