Skip to content

Commit

Permalink
ARM: Better codegen for 64-bit compares.
Browse files Browse the repository at this point in the history
This introduces a custom lowering for ISD::SETCCE (introduced in r253572)
that allows us to emit a short code sequence for 64-bit compares.

Before:

	push	{r7, lr}
	cmp	r0, r2
	mov.w	r0, #0
	mov.w	r12, #0
	it	hs
	movhs	r0, llvm-mirror#1
	cmp	r1, r3
	it	ge
	movge.w	r12, llvm-mirror#1
	it	eq
	moveq	r12, r0
	cmp.w	r12, #0
	bne	.LBB1_2
@ BB#1:                                 @ %bb1
	bl	f
	pop	{r7, pc}
.LBB1_2:                                @ %bb2
	bl	g
	pop	{r7, pc}

After:

	push	{r7, lr}
	subs	r0, r0, r2
	sbcs.w	r0, r1, r3
	bge	.LBB1_2
@ BB#1:                                 @ %bb1
	bl	f
	pop	{r7, pc}
.LBB1_2:                                @ %bb2
	bl	g
	pop	{r7, pc}

Saves around 80KB in Chromium's libchrome.so.

Some notes on this patch:

- I don't much like the ARMISD::BRCOND and ARMISD::CMOV combines I
  introduced (nothing else needs them). However, they are necessary in
  order to avoid poor codegen, and they seem similar to existing combines
  in other backends (e.g. X86 combines (brcond (cmp (setcc Compare))) to
  (brcond Compare)).

- No support for Thumb-1. This is in principle possible, but we'd need
  to implement ARMISD::SUBE for Thumb-1.

Differential Revision: http://reviews.llvm.org/D15256

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263962 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pcc committed Mar 21, 2016
1 parent faf3d27 commit f24c9d4
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 144 deletions.
85 changes: 85 additions & 0 deletions lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,10 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);

// Thumb-1 cannot currently select ARMISD::SUBE.
if (!Subtarget->isThumb1Only())
setOperationAction(ISD::SETCCE, MVT::i32, Custom);

setOperationAction(ISD::BRCOND, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
Expand Down Expand Up @@ -4898,6 +4902,30 @@ static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
return Result;
}

static SDValue LowerSETCCE(SDValue Op, SelectionDAG &DAG) {
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
SDValue Carry = Op.getOperand(2);
SDValue Cond = Op.getOperand(3);
SDLoc DL(Op);

assert(LHS.getSimpleValueType().isInteger() && "SETCCE is integer only.");

assert(Carry.getOpcode() != ISD::CARRY_FALSE);
SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, Carry);

SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
SDValue ARMcc = DAG.getConstant(
IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, ARM::CPSR,
Cmp.getValue(1), SDValue());
return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
CCR, Chain.getValue(1));
}

/// isNEONModifiedImm - Check if the specified splat value corresponds to a
/// valid vector constant for a NEON instruction with a "modified immediate"
/// operand (e.g., VMOV). If so, return the encoded value.
Expand Down Expand Up @@ -7013,6 +7041,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::CTTZ_ZERO_UNDEF: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
case ISD::SETCC: return LowerVSETCC(Op, DAG);
case ISD::SETCCE: return LowerSETCCE(Op, DAG);
case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
Expand Down Expand Up @@ -10639,6 +10668,46 @@ SDValue ARMTargetLowering::PerformCMOVToBFICombine(SDNode *CMOV, SelectionDAG &D
return V;
}

/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
SDValue
ARMTargetLowering::PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const {
SDValue Cmp = N->getOperand(4);
if (Cmp.getOpcode() != ARMISD::CMPZ)
// Only looking at NE cases.
return SDValue();

EVT VT = N->getValueType(0);
SDLoc dl(N);
SDValue LHS = Cmp.getOperand(0);
SDValue RHS = Cmp.getOperand(1);
SDValue Chain = N->getOperand(0);
SDValue BB = N->getOperand(1);
SDValue ARMcc = N->getOperand(2);
ARMCC::CondCodes CC =
(ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();

// (brcond Chain BB ne CPSR (cmpz (and (cmov 0 1 CC CPSR Cmp) 1) 0))
// -> (brcond Chain BB CC CPSR Cmp)
if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
LHS->getOperand(0)->hasOneUse()) {
auto *LHS00C = dyn_cast<ConstantSDNode>(LHS->getOperand(0)->getOperand(0));
auto *LHS01C = dyn_cast<ConstantSDNode>(LHS->getOperand(0)->getOperand(1));
auto *LHS1C = dyn_cast<ConstantSDNode>(LHS->getOperand(1));
auto *RHSC = dyn_cast<ConstantSDNode>(RHS);
if ((LHS00C && LHS00C->getZExtValue() == 0) &&
(LHS01C && LHS01C->getZExtValue() == 1) &&
(LHS1C && LHS1C->getZExtValue() == 1) &&
(RHSC && RHSC->getZExtValue() == 0)) {
return DAG.getNode(
ARMISD::BRCOND, dl, VT, Chain, BB, LHS->getOperand(0)->getOperand(2),
LHS->getOperand(0)->getOperand(3), LHS->getOperand(0)->getOperand(4));
}
}

return SDValue();
}

/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
SDValue
ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const {
Expand Down Expand Up @@ -10692,6 +10761,21 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const {
N->getOperand(3), NewCmp);
}

// (cmov F T ne CPSR (cmpz (cmov 0 1 CC CPSR Cmp) 0))
// -> (cmov F T CC CPSR Cmp)
if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse()) {
auto *LHS0C = dyn_cast<ConstantSDNode>(LHS->getOperand(0));
auto *LHS1C = dyn_cast<ConstantSDNode>(LHS->getOperand(1));
auto *RHSC = dyn_cast<ConstantSDNode>(RHS);
if ((LHS0C && LHS0C->getZExtValue() == 0) &&
(LHS1C && LHS1C->getZExtValue() == 1) &&
(RHSC && RHSC->getZExtValue() == 0)) {
return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
LHS->getOperand(2), LHS->getOperand(3),
LHS->getOperand(4));
}
}

if (Res.getNode()) {
APInt KnownZero, KnownOne;
DAG.computeKnownBits(SDValue(N,0), KnownZero, KnownOne);
Expand Down Expand Up @@ -10742,6 +10826,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
case ISD::ZERO_EXTEND:
case ISD::ANY_EXTEND: return PerformExtendCombine(N, DCI.DAG, Subtarget);
case ARMISD::CMOV: return PerformCMOVCombine(N, DCI.DAG);
case ARMISD::BRCOND: return PerformBRCONDCombine(N, DCI.DAG);
case ISD::LOAD: return PerformLOADCombine(N, DCI);
case ARMISD::VLD2DUP:
case ARMISD::VLD3DUP:
Expand Down
1 change: 1 addition & 0 deletions lib/Target/ARM/ARMISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ namespace llvm {
SDNode *Node) const override;

SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const;
SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const;
SDValue PerformCMOVToBFICombine(SDNode *N, SelectionDAG &DAG) const;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;

Expand Down
168 changes: 72 additions & 96 deletions test/CodeGen/ARM/atomic-64bit.ll
Original file line number Diff line number Diff line change
Expand Up @@ -251,43 +251,37 @@ define i64 @test10(i64* %ptr, i64 %val) {
; CHECK-LABEL: test10:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
; CHECK-LE: cmp [[REG1]], r1
; CHECK-BE: cmp [[REG2]], r2
; CHECK: movwls [[CARRY_LO]], #1
; CHECK-LE: cmp [[REG2]], r2
; CHECK-BE: cmp [[REG1]], r1
; CHECK: movwle [[CARRY_HI]], #1
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK: cmp [[CARRY_HI]], #0
; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
; CHECK: mov [[CMP:[a-z0-9]+]], #0
; CHECK: movwge [[CMP]], #1
; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}

; CHECK-THUMB-LABEL: test10:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0
; CHECK-THUMB-LE: cmp [[REG1]], r2
; CHECK-THUMB-BE: cmp [[REG2]], r3
; CHECK-THUMB: movls.w [[CARRY_LO]], #1
; CHECK-THUMB-LE: cmp [[REG2]], r3
; CHECK-THUMB-BE: cmp [[REG1]], r2
; CHECK-THUMB: movle [[CARRY_HI]], #1
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: cmp [[CARRY_HI]], #0
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
; CHECK-THUMB: movge.w [[CMP]], #1
; CHECK-THUMB: cmp.w [[CMP]], #0
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
Expand All @@ -300,43 +294,37 @@ define i64 @test11(i64* %ptr, i64 %val) {
; CHECK-LABEL: test11:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
; CHECK-LE: cmp [[REG1]], r1
; CHECK-BE: cmp [[REG2]], r2
; CHECK: movwls [[CARRY_LO]], #1
; CHECK-LE: cmp [[REG2]], r2
; CHECK-BE: cmp [[REG1]], r1
; CHECK: movwls [[CARRY_HI]], #1
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK: cmp [[CARRY_HI]], #0
; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
; CHECK: mov [[CMP:[a-z0-9]+]], #0
; CHECK: movwhs [[CMP]], #1
; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}

; CHECK-THUMB-LABEL: test11:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
; CHECK-THUMB-LE: cmp [[REG1]], r2
; CHECK-THUMB-BE: cmp [[REG2]], r3
; CHECK-THUMB: movls.w [[CARRY_LO]], #1
; CHECK-THUMB-LE: cmp [[REG2]], r3
; CHECK-THUMB-BE: cmp [[REG1]], r2
; CHECK-THUMB: movls [[CARRY_HI]], #1
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: cmp [[CARRY_HI]], #0
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
; CHECK-THUMB: movhs.w [[CMP]], #1
; CHECK-THUMB: cmp.w [[CMP]], #0
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
Expand All @@ -349,43 +337,37 @@ define i64 @test12(i64* %ptr, i64 %val) {
; CHECK-LABEL: test12:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
; CHECK-LE: cmp [[REG1]], r1
; CHECK-BE: cmp [[REG2]], r2
; CHECK: movwhi [[CARRY_LO]], #1
; CHECK-LE: cmp [[REG2]], r2
; CHECK-BE: cmp [[REG1]], r1
; CHECK: movwgt [[CARRY_HI]], #1
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK: cmp [[CARRY_HI]], #0
; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
; CHECK: mov [[CMP:[a-z0-9]+]], #0
; CHECK: movwlt [[CMP]], #1
; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}

; CHECK-THUMB-LABEL: test12:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
; CHECK-THUMB-LE: cmp [[REG1]], r2
; CHECK-THUMB-BE: cmp [[REG2]], r3
; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
; CHECK-THUMB-LE: cmp [[REG2]], r3
; CHECK-THUMB-BE: cmp [[REG1]], r2
; CHECK-THUMB: movgt [[CARRY_HI]], #1
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: cmp [[CARRY_HI]], #0
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
; CHECK-THUMB: movlt.w [[CMP]], #1
; CHECK-THUMB: cmp.w [[CMP]], #0
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
Expand All @@ -398,43 +380,37 @@ define i64 @test13(i64* %ptr, i64 %val) {
; CHECK-LABEL: test13:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
; CHECK-LE: cmp [[REG1]], r1
; CHECK-BE: cmp [[REG2]], r2
; CHECK: movwhi [[CARRY_LO]], #1
; CHECK-LE: cmp [[REG2]], r2
; CHECK-BE: cmp [[REG1]], r1
; CHECK: movwhi [[CARRY_HI]], #1
; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK: cmp [[CARRY_HI]], #0
; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
; CHECK: mov [[CMP:[a-z0-9]+]], #0
; CHECK: movwlo [[CMP]], #1
; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}

; CHECK-THUMB-LABEL: test13:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
; CHECK-THUMB-LE: cmp [[REG1]], r2
; CHECK-THUMB-BE: cmp [[REG2]], r3
; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
; CHECK-THUMB-LE: cmp [[REG2]], r3
; CHECK-THUMB-BE: cmp [[REG1]], r2
; CHECK-THUMB: movhi [[CARRY_HI]], #1
; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: cmp [[CARRY_HI]], #0
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
; CHECK-THUMB: movlo.w [[CMP]], #1
; CHECK-THUMB: cmp.w [[CMP]], #0
; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
Expand Down
Loading

0 comments on commit f24c9d4

Please sign in to comment.