diff --git a/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp index a708a171cfc..94b208a8e7d 100644 --- a/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ b/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -712,13 +712,21 @@ bool AArch64ExpandPseudo::expandCMP_SWAP_128( .addReg(DestLo.getReg(), getKillRegState(DestLo.isDead())) .addOperand(DesiredLo) .addImm(0); - BuildMI(LoadCmpBB, DL, TII->get(AArch64::SBCSXr), AArch64::XZR) + BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg) + .addUse(AArch64::WZR) + .addUse(AArch64::WZR) + .addImm(AArch64CC::EQ); + BuildMI(LoadCmpBB, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR) .addReg(DestHi.getReg(), getKillRegState(DestHi.isDead())) - .addOperand(DesiredHi); - BuildMI(LoadCmpBB, DL, TII->get(AArch64::Bcc)) - .addImm(AArch64CC::NE) - .addMBB(DoneBB) - .addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill); + .addOperand(DesiredHi) + .addImm(0); + BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg) + .addUse(StatusReg, RegState::Kill) + .addUse(StatusReg, RegState::Kill) + .addImm(AArch64CC::EQ); + BuildMI(LoadCmpBB, DL, TII->get(AArch64::CBNZW)) + .addUse(StatusReg, RegState::Kill) + .addMBB(DoneBB); LoadCmpBB->addSuccessor(DoneBB); LoadCmpBB->addSuccessor(StoreBB); diff --git a/test/CodeGen/AArch64/cmpxchg-O0.ll b/test/CodeGen/AArch64/cmpxchg-O0.ll index b6918f6ec1c..8432b15ea52 100644 --- a/test/CodeGen/AArch64/cmpxchg-O0.ll +++ b/test/CodeGen/AArch64/cmpxchg-O0.ll @@ -65,8 +65,10 @@ define { i128, i1 } @test_cmpxchg_128(i128* %addr, i128 %desired, i128 %new) nou ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]: ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0] ; CHECK: cmp [[OLD_LO]], x2 -; CHECK: sbcs xzr, [[OLD_HI]], x3 -; CHECK: b.ne [[DONE:.LBB[0-9]+_[0-9]+]] +; CHECK: cset [[CMP_TMP:w[0-9]+]], ne +; CHECK: cmp [[OLD_HI]], x3 +; CHECK: cinc [[CMP:w[0-9]+]], [[CMP_TMP]], ne +; CHECK: cbnz [[CMP]], [[DONE:.LBB[0-9]+_[0-9]+]] ; CHECK: stlxp [[STATUS:w[0-9]+]], x4, x5, [x0] ; CHECK: cbnz [[STATUS]], [[RETRY]] ; CHECK: [[DONE]]: @@ -88,8 +90,10 @@ define {i128, i1} @test_cmpxchg_128_unsplit(i128* %addr) { ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]: ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0] ; CHECK: cmp [[OLD_LO]], [[DESIRED_LO]] -; CHECK: sbcs xzr, [[OLD_HI]], [[DESIRED_HI]] -; CHECK: b.ne [[DONE:.LBB[0-9]+_[0-9]+]] +; CHECK: cset [[CMP_TMP:w[0-9]+]], ne +; CHECK: cmp [[OLD_HI]], [[DESIRED_HI]] +; CHECK: cinc [[CMP:w[0-9]+]], [[CMP_TMP]], ne +; CHECK: cbnz [[CMP]], [[DONE:.LBB[0-9]+_[0-9]+]] ; CHECK: stlxp [[STATUS:w[0-9]+]], [[NEW_LO]], [[NEW_HI]], [x0] ; CHECK: cbnz [[STATUS]], [[RETRY]] ; CHECK: [[DONE]]: