[llvm] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a compare-and-branch (PR #116465)

David Tellenbach via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 17 14:19:31 PST 2024


================
@@ -10396,6 +10398,28 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
                          DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
     }
 
+    // Try to emit Armv9.6 CB instructions. We prefer tb{n}z/cb{n}z due to their
+    // larger branch displacement but do prefer CB over cmp + br.
+    if (Subtarget->hasCMPBR() &&
+        AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
+        ProduceNonFlagSettingCondBr) {
+      AArch64CC::CondCode ACC = changeIntCCToAArch64CC(CC);
+      unsigned Opc = AArch64ISD::CBRR;
+      if (ConstantSDNode *Imm = dyn_cast<ConstantSDNode>(RHS)) {
+        APInt NewImm = Imm->getAPIntValue();
+        if (ACC == AArch64CC::GE || ACC == AArch64CC::HS)
+          NewImm = Imm->getAPIntValue() - 1;
+        else if (ACC == AArch64CC::LE || ACC == AArch64CC::LS)
+          NewImm = Imm->getAPIntValue() + 1;
+
+        if (NewImm.uge(0) && NewImm.ult(64))
+          Opc = AArch64ISD::CBRI;
----------------
dtellenbach wrote:

> aside from a test that at 10 bits of offset we stop emitting these.

That is also covered by the branch-relaxation test: We never stop emitting these even if the branch displacement is not enough but start to relax the branches in these cases. E.g. if

```
0x0    cb<cc> x1, x2, addr_to_far
0x4    fallthrough
```

we still codegen but relax the branch to

```
0x0  cb<cc> x1, x2, 0x8
0x4  b addr_to_far
```

https://github.com/llvm/llvm-project/pull/116465


More information about the llvm-commits mailing list