Index: llvm/lib/Target/AArch64/AArch64MacroFusion.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64MacroFusion.cpp +++ llvm/lib/Target/AArch64/AArch64MacroFusion.cpp @@ -213,6 +213,57 @@ return false; } +// Fuse compare and conditional select. +static bool isCCSelectPair(const MachineInstr *FirstMI, + const MachineInstr &SecondMI) { + unsigned SecondOpcode = SecondMI.getOpcode(); + + // 32 bits + if (SecondOpcode == AArch64::CSELWr) { + // Assume the 1st instr to be a wildcard if it is unspecified. + if (!FirstMI) + return true; + + if (FirstMI->definesRegister(AArch64::WZR)) + switch (FirstMI->getOpcode()) { + case AArch64::SUBSWrs: + if (AArch64InstrInfo::hasShiftedReg(*FirstMI)) + return false; + return true; + case AArch64::SUBSWrx: + if (AArch64InstrInfo::hasExtendedReg(*FirstMI)) + return false; + return true; + case AArch64::SUBSWrr: + case AArch64::SUBSWri: + return true; + } + } + // 64 bits + else if (SecondOpcode == AArch64::CSELXr) { + // Assume the 1st instr to be a wildcard if it is unspecified. + if (!FirstMI) + return true; + + if (FirstMI->definesRegister(AArch64::XZR)) + switch (FirstMI->getOpcode()) { + case AArch64::SUBSXrs: + if (AArch64InstrInfo::hasShiftedReg(*FirstMI)) + return false; + return true; + case AArch64::SUBSXrx: + case AArch64::SUBSXrx64: + if (AArch64InstrInfo::hasExtendedReg(*FirstMI)) + return false; + return true; + case AArch64::SUBSXrr: + case AArch64::SUBSXri: + return true; + } + } + return false; +} + /// \brief Check if the instr pair, FirstMI and SecondMI, should be fused /// together. Given SecondMI, when FirstMI is unspecified, then check if /// SecondMI may be part of a fused pair at all. @@ -232,6 +283,8 @@ return true; if (ST.hasFuseAddress() && isAddressLdStPair(FirstMI, SecondMI)) return true; + if (ST.hasFuseCCSelect() && isCCSelectPair(FirstMI, SecondMI)) + return true; return false; }