Skip to content

[BOLT][AArch64] Add a unittest for compare-and-branch inversion. - #181177

Merged
labrinea merged 7 commits into
llvm:mainfrom
labrinea:comp-and-branch-bolt-unittest
Feb 27, 2026
Merged

labrinea merged 7 commits into
llvm:mainfrom
labrinea:comp-and-branch-bolt-unittest

Conversation

@labrinea

Copy link
Copy Markdown
Contributor

Checks that isReversibleBranch() returns false

  • when the immediate value is 63 and needs +1 adjustment
  • when the immediate value is 0 and needs -1 adjustment

Checks that reverseBranchCondition() adjusts

  • the opcode
  • the immediate operand if necessary (+/-1)
  • the register operands if necessary (swap)

Checks that isReversibleBranch() returns false
 - when the immediate value is 63 and needs +1 adjustment
 - when the immediate value is 0 and needs -1 adjustment

Checks that reverseBranchCondition() adjusts
 - the opcode
 - the immediate operand if necessary (+/-1)
 - the register operands if necessary (swap)
@llvmbot

llvmbot commented Feb 12, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-bolt

Author: Alexandros Lamprineas (labrinea)

Changes

Checks that isReversibleBranch() returns false

  • when the immediate value is 63 and needs +1 adjustment
  • when the immediate value is 0 and needs -1 adjustment

Checks that reverseBranchCondition() adjusts

  • the opcode
  • the immediate operand if necessary (+/-1)
  • the register operands if necessary (swap)

Full diff: https://github.com/llvm/llvm-project/pull/181177.diff

1 Files Affected:

  • (modified) bolt/unittests/Core/MCPlusBuilder.cpp (+57)
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp
index a8d25f3323b38..e11347a8c4c94 100644
--- a/bolt/unittests/Core/MCPlusBuilder.cpp
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -119,6 +119,63 @@ TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
                  /*OnlySmaller=*/true);
 }
 
+TEST_P(MCPlusBuilderTester, AArch64_ReverseCompAndBranch) {
+  if (GetParam() != Triple::aarch64)
+    GTEST_SKIP();
+
+  BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true);
+  std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock();
+  std::unique_ptr<BinaryBasicBlock> TargetBB = BF->createBasicBlock();
+  BB->addSuccessor(TargetBB.get());
+
+  // cbgt x0, #0, target
+  MCInst NeedsImmInc = MCInstBuilder(AArch64::CBGTXri)
+      .addReg(AArch64::X0)
+      .addImm(0)
+      .addExpr(MCSymbolRefExpr::create(TargetBB->getLabel(), *BC->Ctx.get()));
+  BB->addInstruction(NeedsImmInc);
+  // cblo x0, #1, target
+  MCInst NeedsImmDec = MCInstBuilder(AArch64::CBLOXri)
+      .addReg(AArch64::X0)
+      .addImm(1)
+      .addExpr(MCSymbolRefExpr::create(TargetBB->getLabel(), *BC->Ctx.get()));
+  BB->addInstruction(NeedsImmDec);
+  // cbge x0, x1, target
+  MCInst NeedsRegSwap = MCInstBuilder(AArch64::CBGEXrr)
+      .addReg(AArch64::X0)
+      .addReg(AArch64::X1)
+      .addExpr(MCSymbolRefExpr::create(TargetBB->getLabel(), *BC->Ctx.get()));
+  BB->addInstruction(NeedsRegSwap);
+  // cbgt x0, #63, target
+  MCInst Irreversible = MCInstBuilder(AArch64::CBGTXri)
+      .addReg(AArch64::X0)
+      .addImm(63)
+      .addExpr(MCSymbolRefExpr::create(TargetBB->getLabel(), *BC->Ctx.get()));
+  BB->addInstruction(Irreversible);
+
+  auto II = BB->begin();
+  ASSERT_TRUE(BC->MIB->isReversibleBranch(*II));
+  BC->MIB->reverseBranchCondition(*II, TargetBB->getLabel(), BC->Ctx.get());
+  // cblt x0, #1, target
+  ASSERT_EQ(II->getOpcode(), AArch64::CBLTXri);
+  ASSERT_EQ(II->getOperand(1).getImm(), 1);
+  II++;
+  ASSERT_TRUE(BC->MIB->isReversibleBranch(*II));
+  BC->MIB->reverseBranchCondition(*II, TargetBB->getLabel(), BC->Ctx.get());
+  // cbhi x0, #0, target
+  ASSERT_EQ(II->getOpcode(), AArch64::CBHIXri);
+  ASSERT_EQ(II->getOperand(1).getImm(), 0);
+  II++;
+  ASSERT_TRUE(BC->MIB->isReversibleBranch(*II));
+  BC->MIB->reverseBranchCondition(*II, TargetBB->getLabel(), BC->Ctx.get());
+  // cbgt x1, x0, target
+  ASSERT_EQ(II->getOpcode(), AArch64::CBGTXrr);
+  ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X1);
+  ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0);
+  II++;
+  ASSERT_FALSE(BC->MIB->isReversibleBranch(*II));
+}
+
 TEST_P(MCPlusBuilderTester, AArch64_CmpJE) {
   if (GetParam() != Triple::aarch64)
     GTEST_SKIP();

@github-actions

github-actions Bot commented Feb 12, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

@paschalis-mpeis paschalis-mpeis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Alexandre,

Thanks for the unit tests.
Would you mind restructuring it a bit so we list and test each case individually?

Comment thread bolt/unittests/Core/MCPlusBuilder.cpp Outdated

@paschalis-mpeis paschalis-mpeis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks.

@labrinea
labrinea merged commit a71ded3 into llvm:main Feb 27, 2026
10 checks passed
@labrinea
labrinea deleted the comp-and-branch-bolt-unittest branch February 27, 2026 21:09
sujianIBM pushed a commit to sujianIBM/llvm-project that referenced this pull request Mar 5, 2026
…m#181177)

Checks that isReversibleBranch() returns false
 - when the immediate value is 63 and needs +1 adjustment
 - when the immediate value is 0 and needs -1 adjustment

Checks that reverseBranchCondition() adjusts
 - the opcode
 - the immediate operand if necessary (+/-1)
 - the register operands if necessary (swap)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants