[llvm] [Sparc] Optimize compare instruction (PR #167140)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 9 20:14:32 PST 2025
================
@@ -640,6 +640,152 @@ unsigned SparcInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
return get(Opcode).getSize();
}
+bool SparcInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
+ Register &SrcReg2, int64_t &CmpMask,
+ int64_t &CmpValue) const {
+ Register DstReg;
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case SP::SUBCCri:
+ DstReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(1).getReg();
+ SrcReg2 = 0;
+ CmpMask = ~0;
+ CmpValue = MI.getOperand(2).getImm();
+ return (DstReg == SP::G0) && (CmpValue == 0);
+ case SP::SUBCCrr:
+ DstReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(1).getReg();
+ SrcReg2 = MI.getOperand(2).getReg();
+ CmpMask = ~0;
+ CmpValue = 0;
+ return (DstReg == SP::G0) && (SrcReg2 == SP::G0);
+ }
+
+ return false;
+}
+
+bool SparcInstrInfo::optimizeCompareInstr(
+ MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask,
+ int64_t CmpValue, const MachineRegisterInfo *MRI) const {
+
+ // Get the unique definition of SrcReg.
+ MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
+ if (!MI)
+ return false;
+
+ // Only optimize if defining and comparing instruction in same block.
+ if (MI->getParent() != CmpInstr.getParent())
+ return false;
+
+ unsigned newOpcode;
+ switch (MI->getOpcode()) {
+ case SP::ANDNrr:
+ newOpcode = SP::ANDNCCrr;
+ break;
+ case SP::ANDNri:
+ newOpcode = SP::ANDNCCri;
+ break;
+ case SP::ANDrr:
+ newOpcode = SP::ANDCCrr;
+ break;
+ case SP::ANDri:
+ newOpcode = SP::ANDCCri;
+ break;
+ case SP::ORrr:
+ newOpcode = SP::ORCCrr;
+ break;
+ case SP::ORri:
+ newOpcode = SP::ORCCri;
+ break;
+ case SP::ORNCCrr:
+ newOpcode = SP::ORNCCrr;
+ break;
+ case SP::ORNri:
+ newOpcode = SP::ORNCCri;
+ break;
+ case SP::XORrr:
+ newOpcode = SP::XORCCrr;
+ break;
+ case SP::XNORri:
+ newOpcode = SP::XNORCCri;
+ break;
+ case SP::XNORrr:
+ newOpcode = SP::XNORCCrr;
+ break;
+ case SP::ADDrr:
+ newOpcode = SP::ADDCCrr;
+ break;
+ case SP::ADDri:
+ newOpcode = SP::ADDCCri;
+ break;
+ case SP::SUBrr:
+ newOpcode = SP::SUBCCrr;
+ break;
+ case SP::SUBri:
+ newOpcode = SP::SUBCCri;
+ break;
+ default:
+ return false;
+ }
+
+ bool isSafe = false;
+ bool isRegUsed = false;
+ MachineBasicBlock::iterator I = MI;
+ MachineBasicBlock::iterator C = CmpInstr;
+ MachineBasicBlock::iterator E = CmpInstr.getParent()->end();
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+
+ // If ICC is used or modified between MI and CmpInstr we cannot optimize.
+ while (++I != C) {
+ if (I->modifiesRegister(SP::ICC, TRI) || I->readsRegister(SP::ICC, TRI))
+ return false;
+ if (I->readsRegister(SrcReg, TRI))
+ isRegUsed = true;
----------------
koachan wrote:
Think the two should be equivalent. I'll change it anyway since it simplifies the code.
https://github.com/llvm/llvm-project/pull/167140
More information about the llvm-commits
mailing list