[llvm] [BOLT][AArch64] Expand cmpbr when reversing would overflow (PR #202998)
Alexandros Lamprineas via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 6 02:47:46 PDT 2026
================
@@ -2171,38 +2190,74 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
}
- bool isReversibleBranch(const MCInst &Inst) const override {
+ bool isReversibleBranch(const MCInst &Inst,
+ bool MustPreserveFlags = true) const override {
if (isCompAndBranch(Inst)) {
unsigned InvertedOpcode = getInvertedBranchOpcode(Inst.getOpcode());
- if (needsImmDec(InvertedOpcode) && Inst.getOperand(1).getImm() == 0)
+ if (needsImmDec(InvertedOpcode) && Inst.getOperand(1).getImm() == 0 &&
+ MustPreserveFlags)
return false;
- if (needsImmInc(InvertedOpcode) && Inst.getOperand(1).getImm() == 63)
+ if (needsImmInc(InvertedOpcode) && Inst.getOperand(1).getImm() == 63 &&
+ MustPreserveFlags)
return false;
}
return MCPlusBuilder::isReversibleBranch(Inst);
}
- void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB,
- MCContext *Ctx) const override {
- if (!isReversibleBranch(Inst)) {
- errs() << "BOLT-ERROR: Cannot reverse branch " << Inst << "\n";
- exit(1);
- }
+ InstructionListType
+ reverseBranchCondition(MCInst Inst, const MCSymbol *TBB, MCContext *Ctx,
+ bool MustPreserveFlags = true) const override {
+ assert(isReversibleBranch(Inst, MustPreserveFlags) &&
+ "Irreversible branch");
if (isTB(Inst) || isCB(Inst) || isCompAndBranch(Inst)) {
+ bool ImmediateOutOfBounds = false;
unsigned InvertedOpcode = getInvertedBranchOpcode(Inst.getOpcode());
- Inst.setOpcode(InvertedOpcode);
- assert(Inst.getOpcode() != 0 && "Invalid branch instruction");
+ assert(InvertedOpcode != 0 && "Invalid branch instruction");
// The FEAT_CMPBR compare-and-branch instructions cannot encode all
// the possible condition codes, therefore we either have to adjust
// the immediate value by +-1, or to swap the register operands
// when reversing the branch condition.
if (needsRegSwap(InvertedOpcode))
std::swap(Inst.getOperand(0), Inst.getOperand(1));
- else if (needsImmDec(InvertedOpcode))
- Inst.getOperand(1).setImm(Inst.getOperand(1).getImm() - 1);
- else if (needsImmInc(InvertedOpcode))
- Inst.getOperand(1).setImm(Inst.getOperand(1).getImm() + 1);
+ else if (needsImmDec(InvertedOpcode)) {
+ if (Inst.getOperand(1).getImm() == 0)
+ ImmediateOutOfBounds = true;
+ else
+ Inst.getOperand(1).setImm(Inst.getOperand(1).getImm() - 1);
+ } else if (needsImmInc(InvertedOpcode)) {
+ if (Inst.getOperand(1).getImm() == 63)
+ ImmediateOutOfBounds = true;
+ else
+ Inst.getOperand(1).setImm(Inst.getOperand(1).getImm() + 1);
+ }
+ if (ImmediateOutOfBounds) {
+ auto is32BitVariant = [](unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ return false;
+ case AArch64::CBGTWri:
+ case AArch64::CBLTWri:
+ case AArch64::CBHIWri:
+ case AArch64::CBLOWri:
+ return true;
+ }
+ };
+ InstructionListType Code;
+ MCInstBuilder Cmp =
+ is32BitVariant(InvertedOpcode)
+ ? MCInstBuilder(AArch64::SUBSWri).addReg(AArch64::WZR)
+ : MCInstBuilder(AArch64::SUBSXri).addReg(AArch64::XZR);
+ Cmp.addReg(Inst.getOperand(0).getReg())
+ .addImm(Inst.getOperand(1).getImm())
+ .addImm(0);
+ Code.emplace_back(std::move(Cmp));
+ Code.emplace_back(MCInstBuilder(AArch64::Bcc)
----------------
labrinea wrote:
I think we should remove the branch liveness info annotation though
https://github.com/llvm/llvm-project/pull/202998
More information about the llvm-commits
mailing list