[llvm] [AArch64][ISel] Enable profile-aware branch condition merging (PR #201486)
Kunal Pathak via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 3 18:05:20 PDT 2026
https://github.com/kunalspathak created https://github.com/llvm/llvm-project/pull/201486
AArch64 previously inherited the default {-1, -1, -1} for `getJumpConditionMergingParams`, causing `shouldKeepJumpConditionsTogether` in SelectionDAGBuilder to always return false. This meant compound branch conditions (br (and/or cond1, cond2)) were always split into separate basic blocks at the DAG level, and profile data from BranchProbabilityInfo was never consulted for the merge/split decision.
Override `getJumpConditionMergingParams` in AArch64TargetLowering with tunable cl::opt parameters matching the X86 structure. Since `CCMP` is part of the base AArch64 ISA, the `CCMP` bias is applied unconditionally. Default values: `BaseCost=2, CcmpBias=6 (effective threshold 8), LikelyBias=0, UnlikelyBias=-1`.
This enables three improvements:
1. Profile-guided merge/split decisions using BranchProbabilityInfo
2. Smarter compare ordering at the DAG level (e.g., placing large immediates in CMP and small ones in CCMP to respect the 0-31 immediate range)
3. Branch elimination in cases like (a == 5 || b == 32) where the post-ISel CCMP pass previously could not merge due to immediate range constraints
Godbolt: https://godbolt.org/z/PoPGWehjn
>From ed2a2689689d224a6ee6c6432172eee43c0acb22 Mon Sep 17 00:00:00 2001
From: Kunal Pathak <kupathak at fb.com>
Date: Wed, 3 Jun 2026 17:58:33 -0700
Subject: [PATCH] [AArch64][ISel] Enable profile-aware branch condition merging
via getJumpConditionMergingParams
AArch64 previously inherited the default {-1, -1, -1} for
`getJumpConditionMergingParams``, causing `shouldKeepJumpConditionsTogether`
in SelectionDAGBuilder to always return false. This meant compound
branch conditions (br (and/or cond1, cond2)) were always split into
separate basic blocks at the DAG level, and profile data from
BranchProbabilityInfo was never consulted for the merge/split decision.
Override `getJumpConditionMergingParams`` in AArch64TargetLowering with
tunable cl::opt parameters matching the X86 structure. Since CCMP is
part of the base AArch64 ISA, the CCMP bias is applied unconditionally.
Default values: BaseCost=2, CcmpBias=6 (effective threshold 8),
LikelyBias=0, UnlikelyBias=-1.
This enables three improvements:
1. Profile-guided merge/split decisions using BranchProbabilityInfo
2. Smarter compare ordering at the DAG level (e.g., placing large
immediates in CMP and small ones in CCMP to respect the 0-31
immediate range)
3. Branch elimination in cases like (a == 5 || b == 32) where the
post-ISel CCMP pass previously could not merge due to immediate
range constraints
Godbolt: https://godbolt.org/z/M8veW617q
---
.../Target/AArch64/AArch64ISelLowering.cpp | 53 ++++
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 4 +
llvm/test/CodeGen/AArch64/arm64-ccmp.ll | 235 ++++++++++++------
3 files changed, 214 insertions(+), 78 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ec52647135722..e9d0412e45472 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -157,6 +157,47 @@ cl::opt<bool> EnableSVEGISel(
// TODO: This option should be removed once we switch to always using PTRADD in
// the SelectionDAG.
+static cl::opt<int> BrMergingBaseCostThresh(
+ "aarch64-br-merging-base-cost", cl::init(2),
+ cl::desc(
+ "Sets the cost threshold for when multiple conditionals will be merged "
+ "into one branch versus be split in multiple branches. Merging "
+ "conditionals saves branches at the cost of additional instructions. "
+ "This value sets the instruction cost limit, below which conditionals "
+ "will be merged, and above which conditionals will be split. Set to -1 "
+ "to never merge branches."),
+ cl::Hidden);
+
+static cl::opt<int> BrMergingCcmpBias(
+ "aarch64-br-merging-ccmp-bias", cl::init(6),
+ cl::desc("Increases 'aarch64-br-merging-base-cost' to account for the "
+ "CCMP instruction, which is always available on AArch64 and "
+ "makes merging branch conditions cheaper."),
+ cl::Hidden);
+
+static cl::opt<int> BrMergingLikelyBias(
+ "aarch64-br-merging-likely-bias", cl::init(0),
+ cl::desc("Increases 'aarch64-br-merging-base-cost' in cases that it is "
+ "likely that all conditionals will be executed. For example for "
+ "merging the conditionals (a == b && c > d), if its known that "
+ "a == b is likely, then it is likely that if the conditionals are "
+ "split both sides will be executed, so it may be desirable to "
+ "increase the instruction cost threshold. Set to -1 to never "
+ "merge likely branches."),
+ cl::Hidden);
+
+static cl::opt<int> BrMergingUnlikelyBias(
+ "aarch64-br-merging-unlikely-bias", cl::init(-1),
+ cl::desc(
+ "Decreases 'aarch64-br-merging-base-cost' in cases that it is unlikely "
+ "that all conditionals will be executed. For example for merging "
+ "the conditionals (a == b && c > d), if its known that a == b is "
+ "unlikely, then it is unlikely that if the conditionals are split "
+ "both sides will be executed, so it may be desirable to decrease "
+ "the instruction cost threshold. Set to -1 to never merge unlikely "
+ "branches."),
+ cl::Hidden);
+
static cl::opt<bool> UseFEATCPACodegen(
"aarch64-use-featcpa-codegen", cl::Hidden,
cl::desc("Generate ISD::PTRADD nodes for pointer arithmetic in "
@@ -31529,6 +31570,18 @@ bool AArch64TargetLowering::
return X.getValueType().isScalarInteger() || NewShiftOpcode == ISD::SHL;
}
+TargetLoweringBase::CondMergingParams
+AArch64TargetLowering::getJumpConditionMergingParams(
+ Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs) const {
+ int BaseCost = BrMergingBaseCostThresh.getValue();
+ // CCMP is always available on AArch64.
+ if (BaseCost >= 0)
+ BaseCost += BrMergingCcmpBias;
+
+ return {BaseCost, BrMergingLikelyBias.getValue(),
+ BrMergingUnlikelyBias.getValue()};
+}
+
TargetLowering::ShiftLegalizationStrategy
AArch64TargetLowering::preferredShiftLegalizationStrategy(
SelectionDAG &DAG, SDNode *N, unsigned int ExpansionFactor) const {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 7e4c4e1ba25ff..20c476d076b47 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -441,6 +441,10 @@ class AArch64TargetLowering : public TargetLowering {
preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
unsigned ExpansionFactor) const override;
+ CondMergingParams
+ getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
+ const Value *Rhs) const override;
+
bool shouldTransformSignedTruncationCheck(EVT XVT,
unsigned KeptBits) const override {
// For vectors, we don't have a preference..
diff --git a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
index 71d26d25c0515..b3ed2cf27bd97 100644
--- a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
@@ -4,18 +4,31 @@
target triple = "arm64-apple-ios"
define i32 @single_same(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: single_same:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, #5
-; CHECK-NEXT: ccmp w1, #17, #4, ne
-; CHECK-NEXT: b.ne LBB0_2
-; CHECK-NEXT: ; %bb.1: ; %if.then
-; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT: bl _foo
-; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT: LBB0_2: ; %if.end
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: single_same:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w1, #17
+; CHECK-SD-NEXT: ccmp w0, #5, #4, ne
+; CHECK-SD-NEXT: b.ne LBB0_2
+; CHECK-SD-NEXT: ; %bb.1: ; %if.then
+; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-SD-NEXT: bl _foo
+; CHECK-SD-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-SD-NEXT: LBB0_2: ; %if.end
+; CHECK-SD-NEXT: mov w0, #7 ; =0x7
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: single_same:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, #5
+; CHECK-GI-NEXT: ccmp w1, #17, #4, ne
+; CHECK-GI-NEXT: b.ne LBB0_2
+; CHECK-GI-NEXT: ; %bb.1: ; %if.then
+; CHECK-GI-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-GI-NEXT: bl _foo
+; CHECK-GI-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-GI-NEXT: LBB0_2: ; %if.end
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
entry:
%cmp = icmp eq i32 %a, 5
%cmp1 = icmp eq i32 %b, 17
@@ -34,9 +47,9 @@ if.end:
define i32 @single_different(i32 %a, i32 %b) nounwind ssp {
; CHECK-SD-LABEL: single_different:
; CHECK-SD: ; %bb.0: ; %entry
-; CHECK-SD-NEXT: cmp w0, #6
-; CHECK-SD-NEXT: ccmp w1, #17, #0, ge
-; CHECK-SD-NEXT: b.eq LBB1_2
+; CHECK-SD-NEXT: cmp w1, #17
+; CHECK-SD-NEXT: ccmp w0, #5, #4, eq
+; CHECK-SD-NEXT: b.gt LBB1_2
; CHECK-SD-NEXT: ; %bb.1: ; %if.then
; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
; CHECK-SD-NEXT: bl _foo
@@ -276,17 +289,31 @@ if.end:
; Chain multiple compares.
define void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp {
-; CHECK-LABEL: multi_different:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, w1
-; CHECK-NEXT: sdiv w8, w1, w0
-; CHECK-NEXT: ccmp w8, #5, #0, gt
-; CHECK-NEXT: ccmp w8, w2, #4, eq
-; CHECK-NEXT: b.gt LBB6_2
-; CHECK-NEXT: ; %bb.1: ; %if.end
-; CHECK-NEXT: ret
-; CHECK-NEXT: LBB6_2: ; %if.then
-; CHECK-NEXT: b _foo
+; CHECK-SD-LABEL: multi_different:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w0, w1
+; CHECK-SD-NEXT: b.le LBB6_3
+; CHECK-SD-NEXT: ; %bb.1: ; %land.lhs.true
+; CHECK-SD-NEXT: sdiv w8, w1, w0
+; CHECK-SD-NEXT: cmp w8, w2
+; CHECK-SD-NEXT: ccmp w8, #5, #0, gt
+; CHECK-SD-NEXT: b.ne LBB6_3
+; CHECK-SD-NEXT: ; %bb.2: ; %if.then
+; CHECK-SD-NEXT: b _foo
+; CHECK-SD-NEXT: LBB6_3: ; %if.end
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: multi_different:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, w1
+; CHECK-GI-NEXT: sdiv w8, w1, w0
+; CHECK-GI-NEXT: ccmp w8, #5, #0, gt
+; CHECK-GI-NEXT: ccmp w8, w2, #4, eq
+; CHECK-GI-NEXT: b.gt LBB6_2
+; CHECK-GI-NEXT: ; %bb.1: ; %if.end
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: LBB6_2: ; %if.then
+; CHECK-GI-NEXT: b _foo
entry:
%cmp = icmp sgt i32 %a, %b
br i1 %cmp, label %land.lhs.true, label %if.end
@@ -308,18 +335,31 @@ if.end:
; Convert a cbz in the head block.
define i32 @cbz_head(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: cbz_head:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: ccmp w1, #17, #0, ne
-; CHECK-NEXT: b.eq LBB7_2
-; CHECK-NEXT: ; %bb.1: ; %if.then
-; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT: bl _foo
-; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT: LBB7_2: ; %if.end
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: cbz_head:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w1, #17
+; CHECK-SD-NEXT: ccmp w0, #0, #4, eq
+; CHECK-SD-NEXT: b.ne LBB7_2
+; CHECK-SD-NEXT: ; %bb.1: ; %if.then
+; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-SD-NEXT: bl _foo
+; CHECK-SD-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-SD-NEXT: LBB7_2: ; %if.end
+; CHECK-SD-NEXT: mov w0, #7 ; =0x7
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: cbz_head:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, #0
+; CHECK-GI-NEXT: ccmp w1, #17, #0, ne
+; CHECK-GI-NEXT: b.eq LBB7_2
+; CHECK-GI-NEXT: ; %bb.1: ; %if.then
+; CHECK-GI-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-GI-NEXT: bl _foo
+; CHECK-GI-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-GI-NEXT: LBB7_2: ; %if.end
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
entry:
%cmp = icmp eq i32 %a, 0
%cmp1 = icmp ne i32 %b, 17
@@ -338,22 +378,35 @@ if.end:
; smaller range of immediates than subs/adds.
; The ccmp immediates must be in the range 0-31.
define i32 @immediate_range(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: immediate_range:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, #5
-; CHECK-NEXT: b.eq LBB8_3
-; CHECK-NEXT: ; %bb.1: ; %entry
-; CHECK-NEXT: cmp w1, #32
-; CHECK-NEXT: b.eq LBB8_3
-; CHECK-NEXT: ; %bb.2: ; %if.end
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
-; CHECK-NEXT: LBB8_3: ; %if.then
-; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT: bl _foo
-; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: immediate_range:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w1, #32
+; CHECK-SD-NEXT: ccmp w0, #5, #4, ne
+; CHECK-SD-NEXT: b.ne LBB8_2
+; CHECK-SD-NEXT: ; %bb.1: ; %if.then
+; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-SD-NEXT: bl _foo
+; CHECK-SD-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-SD-NEXT: LBB8_2: ; %if.end
+; CHECK-SD-NEXT: mov w0, #7 ; =0x7
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: immediate_range:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, #5
+; CHECK-GI-NEXT: b.eq LBB8_3
+; CHECK-GI-NEXT: ; %bb.1: ; %entry
+; CHECK-GI-NEXT: cmp w1, #32
+; CHECK-GI-NEXT: b.eq LBB8_3
+; CHECK-GI-NEXT: ; %bb.2: ; %if.end
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: LBB8_3: ; %if.then
+; CHECK-GI-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-GI-NEXT: bl _foo
+; CHECK-GI-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
entry:
%cmp = icmp eq i32 %a, 5
%cmp1 = icmp eq i32 %b, 32
@@ -370,18 +423,31 @@ if.end:
; Convert a cbz in the second block.
define i32 @cbz_second(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: cbz_second:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: ccmp w1, #0, #0, ne
-; CHECK-NEXT: b.eq LBB9_2
-; CHECK-NEXT: ; %bb.1: ; %if.then
-; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT: bl _foo
-; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT: LBB9_2: ; %if.end
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: cbz_second:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w1, #0
+; CHECK-SD-NEXT: ccmp w0, #0, #4, eq
+; CHECK-SD-NEXT: b.ne LBB9_2
+; CHECK-SD-NEXT: ; %bb.1: ; %if.then
+; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-SD-NEXT: bl _foo
+; CHECK-SD-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-SD-NEXT: LBB9_2: ; %if.end
+; CHECK-SD-NEXT: mov w0, #7 ; =0x7
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: cbz_second:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, #0
+; CHECK-GI-NEXT: ccmp w1, #0, #0, ne
+; CHECK-GI-NEXT: b.eq LBB9_2
+; CHECK-GI-NEXT: ; %bb.1: ; %if.then
+; CHECK-GI-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-GI-NEXT: bl _foo
+; CHECK-GI-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-GI-NEXT: LBB9_2: ; %if.end
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
entry:
%cmp = icmp eq i32 %a, 0
%cmp1 = icmp ne i32 %b, 0
@@ -398,18 +464,31 @@ if.end:
; Convert a cbnz in the second block.
define i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: cbnz_second:
-; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: ccmp w1, #0, #4, ne
-; CHECK-NEXT: b.ne LBB10_2
-; CHECK-NEXT: ; %bb.1: ; %if.then
-; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT: bl _foo
-; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT: LBB10_2: ; %if.end
-; CHECK-NEXT: mov w0, #7 ; =0x7
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: cbnz_second:
+; CHECK-SD: ; %bb.0: ; %entry
+; CHECK-SD-NEXT: cmp w1, #0
+; CHECK-SD-NEXT: ccmp w0, #0, #4, ne
+; CHECK-SD-NEXT: b.ne LBB10_2
+; CHECK-SD-NEXT: ; %bb.1: ; %if.then
+; CHECK-SD-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-SD-NEXT: bl _foo
+; CHECK-SD-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-SD-NEXT: LBB10_2: ; %if.end
+; CHECK-SD-NEXT: mov w0, #7 ; =0x7
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: cbnz_second:
+; CHECK-GI: ; %bb.0: ; %entry
+; CHECK-GI-NEXT: cmp w0, #0
+; CHECK-GI-NEXT: ccmp w1, #0, #4, ne
+; CHECK-GI-NEXT: b.ne LBB10_2
+; CHECK-GI-NEXT: ; %bb.1: ; %if.then
+; CHECK-GI-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-GI-NEXT: bl _foo
+; CHECK-GI-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-GI-NEXT: LBB10_2: ; %if.end
+; CHECK-GI-NEXT: mov w0, #7 ; =0x7
+; CHECK-GI-NEXT: ret
entry:
%cmp = icmp eq i32 %a, 0
%cmp1 = icmp eq i32 %b, 0
More information about the llvm-commits
mailing list