Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ static cl::opt<bool> UseFEATCPACodegen(
/// Value type used for condition codes.
static const MVT MVT_CC = MVT::i32;

/// Value type used for NZCV flags.
static constexpr MVT FlagsVT = MVT::i32;

static const MCPhysReg GPRArgRegs[] = {AArch64::X0, AArch64::X1, AArch64::X2,
AArch64::X3, AArch64::X4, AArch64::X5,
AArch64::X6, AArch64::X7};
Expand Down Expand Up @@ -3451,7 +3454,7 @@ static SDValue emitStrictFPComparison(SDValue LHS, SDValue RHS, const SDLoc &DL,
}
unsigned Opcode =
IsSignaling ? AArch64ISD::STRICT_FCMPE : AArch64ISD::STRICT_FCMP;
return DAG.getNode(Opcode, DL, {MVT::i32, MVT::Other}, {Chain, LHS, RHS});
return DAG.getNode(Opcode, DL, {FlagsVT, MVT::Other}, {Chain, LHS, RHS});
}

static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
Expand All @@ -3465,7 +3468,7 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
LHS = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, LHS);
RHS = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, RHS);
}
return DAG.getNode(AArch64ISD::FCMP, DL, MVT::i32, LHS, RHS);
return DAG.getNode(AArch64ISD::FCMP, DL, FlagsVT, LHS, RHS);
}

// The CMP instruction is just an alias for SUBS, and representing it as
Expand All @@ -3490,7 +3493,7 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
// (a.k.a. ANDS) except that the flags are only guaranteed to work for one
// of the signed comparisons.
const SDValue ANDSNode =
DAG.getNode(AArch64ISD::ANDS, DL, DAG.getVTList(VT, MVT_CC),
DAG.getNode(AArch64ISD::ANDS, DL, DAG.getVTList(VT, FlagsVT),
LHS.getOperand(0), LHS.getOperand(1));
// Replace all users of (and X, Y) with newly generated (ands X, Y)
DAG.ReplaceAllUsesWith(LHS, ANDSNode);
Expand All @@ -3501,7 +3504,7 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
}
}

return DAG.getNode(Opcode, DL, DAG.getVTList(VT, MVT_CC), LHS, RHS)
return DAG.getNode(Opcode, DL, DAG.getVTList(VT, FlagsVT), LHS, RHS)
.getValue(1);
}

Expand Down Expand Up @@ -3597,7 +3600,7 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
AArch64CC::CondCode InvOutCC = AArch64CC::getInvertedCondCode(OutCC);
unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(InvOutCC);
SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
return DAG.getNode(Opcode, DL, MVT_CC, LHS, RHS, NZCVOp, Condition, CCOp);
return DAG.getNode(Opcode, DL, FlagsVT, LHS, RHS, NZCVOp, Condition, CCOp);
}

/// Returns true if @p Val is a tree of AND/OR/SETCC operations that can be
Expand Down Expand Up @@ -4036,7 +4039,7 @@ getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
Value = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mul);

// Check that the result fits into a 32-bit integer.
SDVTList VTs = DAG.getVTList(MVT::i64, MVT_CC);
SDVTList VTs = DAG.getVTList(MVT::i64, FlagsVT);
if (IsSigned) {
// cmp xreg, wreg, sxtw
SDValue SExtMul = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Value);
Expand All @@ -4059,12 +4062,12 @@ getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
DAG.getConstant(63, DL, MVT::i64));
// It is important that LowerBits is last, otherwise the arithmetic
// shift will not be folded into the compare (SUBS).
SDVTList VTs = DAG.getVTList(MVT::i64, MVT::i32);
SDVTList VTs = DAG.getVTList(MVT::i64, FlagsVT);
Overflow = DAG.getNode(AArch64ISD::SUBS, DL, VTs, UpperBits, LowerBits)
.getValue(1);
} else {
SDValue UpperBits = DAG.getNode(ISD::MULHU, DL, MVT::i64, LHS, RHS);
SDVTList VTs = DAG.getVTList(MVT::i64, MVT::i32);
SDVTList VTs = DAG.getVTList(MVT::i64, FlagsVT);
Overflow =
DAG.getNode(AArch64ISD::SUBS, DL, VTs,
DAG.getConstant(0, DL, MVT::i64),
Expand All @@ -4075,7 +4078,7 @@ getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
} // switch (...)

if (Opc) {
SDVTList VTs = DAG.getVTList(Op->getValueType(0), MVT::i32);
SDVTList VTs = DAG.getVTList(Op->getValueType(0), FlagsVT);

// Emit the AArch64 operation with overflow check.
Value = DAG.getNode(Opc, DL, VTs, LHS, RHS);
Expand Down Expand Up @@ -4177,7 +4180,7 @@ static SDValue valueToCarryFlag(SDValue Value, SelectionDAG &DAG, bool Invert) {
SDValue Op0 = Invert ? DAG.getConstant(0, DL, VT) : Value;
SDValue Op1 = Invert ? Value : DAG.getConstant(1, DL, VT);
SDValue Cmp =
DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::Glue), Op0, Op1);
DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, FlagsVT), Op0, Op1);
return Cmp.getValue(1);
}

Expand Down Expand Up @@ -4222,7 +4225,7 @@ static SDValue lowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG,
SDLoc DL(Op);
SDVTList VTs = DAG.getVTList(VT0, VT1);

SDValue Sum = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::Glue), OpLHS,
SDValue Sum = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, FlagsVT), OpLHS,
OpRHS, OpCarryIn);

SDValue OutFlag =
Expand Down Expand Up @@ -7037,9 +7040,8 @@ SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
Op.getOperand(0));
// Generate SUBS & CSEL.
SDValue Cmp =
DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::i32),
Op.getOperand(0), DAG.getConstant(0, DL, VT));
SDValue Cmp = DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, FlagsVT),
Op.getOperand(0), DAG.getConstant(0, DL, VT));
return DAG.getNode(AArch64ISD::CSEL, DL, VT, Op.getOperand(0), Neg,
DAG.getConstant(AArch64CC::PL, DL, MVT::i32),
Cmp.getValue(1));
Expand Down Expand Up @@ -11108,7 +11110,7 @@ SDValue AArch64TargetLowering::LowerSETCCCARRY(SDValue Op,
SDValue Carry = Op.getOperand(2);
// SBCS uses a carry not a borrow so the carry flag should be inverted first.
SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
SDValue Cmp = DAG.getNode(AArch64ISD::SBCS, DL, DAG.getVTList(VT, MVT::Glue),
SDValue Cmp = DAG.getNode(AArch64ISD::SBCS, DL, DAG.getVTList(VT, FlagsVT),
LHS, RHS, InvCarry);

EVT OpVT = Op.getValueType();
Expand Down Expand Up @@ -12441,10 +12443,10 @@ SDValue AArch64TargetLowering::LowerAsmOutputForConstraint(

// Get NZCV register. Only update chain when copyfrom is glued.
if (Glue.getNode()) {
Glue = DAG.getCopyFromReg(Chain, DL, AArch64::NZCV, MVT::i32, Glue);
Glue = DAG.getCopyFromReg(Chain, DL, AArch64::NZCV, FlagsVT, Glue);
Chain = Glue.getValue(1);
} else
Glue = DAG.getCopyFromReg(Chain, DL, AArch64::NZCV, MVT::i32);
Glue = DAG.getCopyFromReg(Chain, DL, AArch64::NZCV, FlagsVT);
// Extract CC code.
SDValue CC = getSETCC(Cond, Glue, DL, DAG);

Expand Down Expand Up @@ -18593,7 +18595,7 @@ AArch64TargetLowering::BuildSREMPow2(SDNode *N, const APInt &Divisor,
Created.push_back(And.getNode());
} else {
SDValue CCVal = DAG.getConstant(AArch64CC::MI, DL, MVT_CC);
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
SDVTList VTs = DAG.getVTList(VT, FlagsVT);

SDValue Negs = DAG.getNode(AArch64ISD::SUBS, DL, VTs, Zero, N0);
SDValue AndPos = DAG.getNode(ISD::AND, DL, VT, N0, Pow2MinusOne);
Expand Down Expand Up @@ -19482,10 +19484,10 @@ static SDValue performANDORCSELCombine(SDNode *N, SelectionDAG &DAG) {
// can select to CCMN to avoid the extra mov
SDValue AbsOp1 =
DAG.getConstant(Op1->getAPIntValue().abs(), DL, Op1->getValueType(0));
CCmp = DAG.getNode(AArch64ISD::CCMN, DL, MVT_CC, Cmp1.getOperand(0), AbsOp1,
NZCVOp, Condition, Cmp0);
CCmp = DAG.getNode(AArch64ISD::CCMN, DL, FlagsVT, Cmp1.getOperand(0),
AbsOp1, NZCVOp, Condition, Cmp0);
} else {
CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, Cmp1.getOperand(0),
CCmp = DAG.getNode(AArch64ISD::CCMP, DL, FlagsVT, Cmp1.getOperand(0),
Cmp1.getOperand(1), NZCVOp, Condition, Cmp0);
}
return DAG.getNode(AArch64ISD::CSEL, DL, VT, CSel0.getOperand(0),
Expand Down Expand Up @@ -25134,8 +25136,9 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
if (!TReassocOp && !FReassocOp)
return SDValue();

SDValue NewCmp = DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
DAG.getVTList(VT, MVT_CC), CmpOpOther, SubsOp);
SDValue NewCmp =
DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
DAG.getVTList(VT, FlagsVT), CmpOpOther, SubsOp);

auto Reassociate = [&](SDValue ReassocOp, unsigned OpNum) {
if (!ReassocOp)
Expand Down Expand Up @@ -27161,7 +27164,7 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
: AArch64SysReg::RNDRRS);
SDLoc DL(N);
SDValue A = DAG.getNode(
AArch64ISD::MRS, DL, DAG.getVTList(MVT::i64, MVT::i32, MVT::Other),
AArch64ISD::MRS, DL, DAG.getVTList(MVT::i64, FlagsVT, MVT::Other),
N->getOperand(0), DAG.getConstant(Register, DL, MVT::i32));
SDValue B = DAG.getNode(
AArch64ISD::CSINC, DL, MVT::i32, DAG.getConstant(0, DL, MVT::i32),
Expand Down
23 changes: 12 additions & 11 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -430,26 +430,27 @@ def UseWzrToVecMove : Predicate<"Subtarget->useWzrToVecMove()">;
def SDTBinaryArithWithFlagsOut : SDTypeProfile<2, 2,
[SDTCisSameAs<0, 2>,
SDTCisSameAs<0, 3>,
SDTCisInt<0>, SDTCisVT<1, i32>]>;
SDTCisInt<0>,
SDTCisVT<1, FlagsVT>]>;

// SDTBinaryArithWithFlagsIn - RES1, FLAGS = op LHS, RHS, FLAGS
def SDTBinaryArithWithFlagsIn : SDTypeProfile<1, 3,
[SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>,
SDTCisInt<0>,
SDTCisVT<3, i32>]>;
SDTCisVT<3, FlagsVT>]>;

// SDTBinaryArithWithFlagsInOut - RES1, FLAGS = op LHS, RHS, FLAGS
def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
[SDTCisSameAs<0, 2>,
SDTCisSameAs<0, 3>,
SDTCisInt<0>,
SDTCisVT<1, i32>,
SDTCisVT<4, i32>]>;
SDTCisVT<1, FlagsVT>,
SDTCisVT<4, FlagsVT>]>;

def SDT_AArch64Brcond : SDTypeProfile<0, 3,
[SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>,
SDTCisVT<2, i32>]>;
SDTCisVT<2, FlagsVT>]>;
def SDT_AArch64cbz : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisVT<1, OtherVT>]>;
def SDT_AArch64tbz : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>,
SDTCisVT<2, OtherVT>]>;
Expand All @@ -458,22 +459,22 @@ def SDT_AArch64CSel : SDTypeProfile<1, 4,
[SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>,
SDTCisInt<3>,
SDTCisVT<4, i32>]>;
SDTCisVT<4, FlagsVT>]>;
def SDT_AArch64CCMP : SDTypeProfile<1, 5,
[SDTCisVT<0, i32>,
[SDTCisVT<0, FlagsVT>,
SDTCisInt<1>,
SDTCisSameAs<1, 2>,
SDTCisInt<3>,
SDTCisInt<4>,
SDTCisVT<5, i32>]>;
def SDT_AArch64FCCMP : SDTypeProfile<1, 5,
[SDTCisVT<0, i32>,
[SDTCisVT<0, FlagsVT>,
SDTCisFP<1>,
SDTCisSameAs<1, 2>,
SDTCisInt<3>,
SDTCisInt<4>,
SDTCisVT<5, i32>]>;
def SDT_AArch64FCmp : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
def SDT_AArch64FCmp : SDTypeProfile<1, 2, [SDTCisVT<0, FlagsVT>,
SDTCisFP<1>,
SDTCisSameAs<2, 1>]>;
def SDT_AArch64Rev : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>]>;
Expand Down Expand Up @@ -1124,10 +1125,10 @@ def AArch64probedalloca
SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
[SDNPHasChain, SDNPMayStore]>;

// MRS, also sets the flags via a glue.
// MRS, also sets the flags.
def AArch64mrs : SDNode<"AArch64ISD::MRS",
SDTypeProfile<2, 1, [SDTCisVT<0, i64>,
SDTCisVT<1, i32>,
SDTCisVT<1, FlagsVT>,
SDTCisVT<2, i32>]>,
[SDNPHasChain]>;

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AArch64/AArch64RegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ def GPR64pi48 : RegisterOperand<GPR64, "printPostIncOperand<48>">;
def GPR64pi64 : RegisterOperand<GPR64, "printPostIncOperand<64>">;

// Condition code regclass.
def CCR : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
defvar FlagsVT = i32;
def CCR : RegisterClass<"AArch64", [FlagsVT], 32, (add NZCV)> {
let CopyCost = -1; // Don't allow copying of status registers.

// CCR is not allocatable.
Expand Down
23 changes: 21 additions & 2 deletions llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,29 @@ AArch64SelectionDAGInfo::AArch64SelectionDAGInfo()

void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
const SDNode *N) const {
SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);

#ifndef NDEBUG
// Some additional checks not yet implemented by verifyTargetNode.
constexpr MVT FlagsVT = MVT::i32;
switch (N->getOpcode()) {
default:
return SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
case AArch64ISD::SUBS:
assert(N->getValueType(1) == FlagsVT);
break;
case AArch64ISD::ADC:
case AArch64ISD::SBC:
assert(N->getOperand(2).getValueType() == FlagsVT);
break;
case AArch64ISD::ADCS:
case AArch64ISD::SBCS:
assert(N->getValueType(1) == FlagsVT);
assert(N->getOperand(2).getValueType() == FlagsVT);
break;
case AArch64ISD::CSEL:
case AArch64ISD::CSINC:
case AArch64ISD::BRCOND:
assert(N->getOperand(3).getValueType() == FlagsVT);
break;
case AArch64ISD::SADDWT:
case AArch64ISD::SADDWB:
case AArch64ISD::UADDWT:
Expand Down
20 changes: 8 additions & 12 deletions llvm/test/CodeGen/AArch64/abds-neg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x8, x8, x10, lt
; CHECK-NEXT: csel x9, x9, x11, lt
; CHECK-NEXT: negs x0, x8
Expand All @@ -222,8 +221,7 @@ define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x8, x8, x10, lt
; CHECK-NEXT: csel x9, x9, x11, lt
; CHECK-NEXT: negs x0, x8
Expand Down Expand Up @@ -389,14 +387,12 @@ define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_cmp_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: cmp x0, x2
; CHECK-NEXT: sbc x8, x1, x3
; CHECK-NEXT: subs x9, x2, x0
; CHECK-NEXT: sbc x10, x3, x1
; CHECK-NEXT: subs x11, x0, x2
; CHECK-NEXT: sbcs xzr, x1, x3
; CHECK-NEXT: csel x0, x11, x9, lt
; CHECK-NEXT: csel x1, x8, x10, lt
; CHECK-NEXT: subs x8, x2, x0
; CHECK-NEXT: sbc x9, x3, x1
; CHECK-NEXT: subs x10, x0, x2
; CHECK-NEXT: sbcs x11, x1, x3
; CHECK-NEXT: csel x0, x10, x8, lt
; CHECK-NEXT: csel x1, x11, x9, lt
; CHECK-NEXT: ret
%cmp = icmp slt i128 %a, %b
%ab = sub i128 %a, %b
Expand Down
15 changes: 5 additions & 10 deletions llvm/test/CodeGen/AArch64/abds.ll
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,7 @@ define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x0, x8, x10, lt
; CHECK-NEXT: csel x1, x9, x11, lt
; CHECK-NEXT: ret
Expand All @@ -202,8 +201,7 @@ define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x0, x8, x10, lt
; CHECK-NEXT: csel x1, x9, x11, lt
; CHECK-NEXT: ret
Expand Down Expand Up @@ -279,8 +277,7 @@ define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x0, x8, x10, lt
; CHECK-NEXT: csel x1, x9, x11, lt
; CHECK-NEXT: ret
Expand Down Expand Up @@ -358,8 +355,7 @@ define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x0, x8, x10, lt
; CHECK-NEXT: csel x1, x9, x11, lt
; CHECK-NEXT: ret
Expand Down Expand Up @@ -607,8 +603,7 @@ define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
; CHECK-NEXT: subs x8, x0, x2
; CHECK-NEXT: sbc x9, x1, x3
; CHECK-NEXT: subs x10, x2, x0
; CHECK-NEXT: sbc x11, x3, x1
; CHECK-NEXT: sbcs xzr, x3, x1
; CHECK-NEXT: sbcs x11, x3, x1
; CHECK-NEXT: csel x0, x8, x10, lt
; CHECK-NEXT: csel x1, x9, x11, lt
; CHECK-NEXT: ret
Expand Down
Loading
Loading