Repository: llvm/llvm-project
File: bolt/unittests/Core/MCPlusBuilder.cpp (C++)

Code before:
                 {AArch64::W0, AArch64::W0_HI, AArch64::X0, AArch64::W0_W1,
                  AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7});
}

TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
  testRegAliases(Triple::aarch64, AArch64::X0,
                 {AArch64::W0, AArch64::W0_HI, AArch64::X0},
                 /*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 CompRegNeedsRegSwap = MCInstBuilder(AArch64::CBGEXrr)
                                   .addReg(AArch64::X0)
                                   .addReg(AArch64::X1)
                                   .addExpr(MCSymbolRefExpr::create(
                                       TargetBB->getLabel(), *BC->Ctx.get()));
  BB->addInstruction(CompRegNeedsRegSwap);
  // cbbhi w0, w1, target
  MCInst CompByteNeedsRegSwap = MCInstBuilder(AArch64::CBBHIWrr)
                                    .addReg(AArch64::W0)
                                    .addReg(AArch64::W1)
                                    .addExpr(MCSymbolRefExpr::create(
                                        TargetBB->getLabel(), *BC->Ctx.get()));
  BB->addInstruction(CompByteNeedsRegSwap);
  // cbhhs w0, w1, target
  MCInst CompHalfNeedsRegSwap = MCInstBuilder(AArch64::CBHHSWrr)
                                    .addReg(AArch64::W0)
                                    .addReg(AArch64::W1)

Review comment (suggestion):
```cpp
  // Reverse branch: increase immediate:
  // cbgt x0, #0, target -> cblt x0, #1, target
  MCInst NeedsImmInc = MCInstBuilder(AArch64::CBGTXri)
                           .addReg(AArch64::X0)
                           .addImm(0)
                           .addExpr(MCSymbolRefExpr::create(
                               TargetBB->getLabel(), *BC->Ctx.get()));
  ASSERT_TRUE(BC->MIB->isReversibleBranch(NeedsImmInc));

  BC->MIB->reverseBranchCondition(NeedsImmInc, TargetBB->getLabel(), BC->Ctx.get());
  ASSERT_EQ(NeedsImmInc.getOpcode(), AArch64::CBLTXri);
  ASSERT_EQ(NeedsImmInc.getOperand(1).getImm(), 1);

  // ... next case
```

Code after:
                 {AArch64::W0, AArch64::W0_HI, AArch64::X0, AArch64::W0_W1,
                  AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7});
}

TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
  testRegAliases(Triple::aarch64, AArch64::X0,
                 {AArch64::W0, AArch64::W0_HI, AArch64::X0},
                 /*OnlySmaller=*/true);
}

TEST_P(MCPlusBuilderTester, AArch64_ReverseCompAndBranch) {
  if (GetParam() != Triple::aarch64)
    GTEST_SKIP();

  BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true);
  std::unique_ptr<BinaryBasicBlock> TargetBB = BF->createBasicBlock();

  // Compare register with immediate and branch.
  // Inversion requires incrementing the immediate value.
  // cbgt x0, #0, target ~> cblt x0, #1, target
  MCInst NeedsImmInc = MCInstBuilder(AArch64::CBGTXri)
                           .addReg(AArch64::X0)
                           .addImm(0)
                           .addExpr(MCSymbolRefExpr::create(
                               TargetBB->getLabel(), *BC->Ctx.get()));
  ASSERT_TRUE(BC->MIB->isReversibleBranch(NeedsImmInc));
  BC->MIB->reverseBranchCondition(NeedsImmInc, TargetBB->getLabel(),
                                  BC->Ctx.get());
  ASSERT_EQ(NeedsImmInc.getOpcode(), AArch64::CBLTXri);
  ASSERT_EQ(NeedsImmInc.getOperand(1).getImm(), 1);

  // Compare register with immediate and branch.
  // Inversion requires decrementing the immediate value.
  // cblo x0, #1, target ~> cbhi x0, #0, target
  MCInst NeedsImmDec = MCInstBuilder(AArch64::CBLOXri)
                           .addReg(AArch64::X0)
                           .addImm(1)
                           .addExpr(MCSymbolRefExpr::create(
                               TargetBB->getLabel(), *BC->Ctx.get()));
  ASSERT_TRUE(BC->MIB->isReversibleBranch(NeedsImmDec));
  BC->MIB->reverseBranchCondition(NeedsImmDec, TargetBB->getLabel(),
                                  BC->Ctx.get());
  ASSERT_EQ(NeedsImmDec.getOpcode(), AArch64::CBHIXri);
  ASSERT_EQ(NeedsImmDec.getOperand(1).getImm(), 0);

  // Compare registers and branch.
  // Inversion requires swapping registers.
  // cbge x0, x1, target ~> cbgt x1, x0, target
  MCInst CompRegNeedsRegSwap = MCInstBuilder(AArch64::CBGEXrr)
                                   .addReg(AArch64::X0)
                                   .addReg(AArch64::X1)