llvm.org GIT mirror llvm / b2d6212
Merging r288418: ------------------------------------------------------------------------ r288418 | tnorthover | 2016-12-01 13:31:59 -0800 (Thu, 01 Dec 2016) | 13 lines AArch64: fix 128-bit cmpxchg at -O0 (again, again). This time the issue is fortunately just a simple mistake rather than a horrible design spectre. I thought SUBS/SBCS provided sufficient NZCV flags for comparing two 64-bit values, but they don't. The fix is slightly clunkier in AArch64 because we can't use conditional execution to emit a pair of CMPs. Traditionally an "icmp ne i128" would map to an EOR/EOR/ORR/CBNZ, but that uses more registers so it's easier to go with a CSET/CINC/CBNZ combination. Slightly less efficient, but this is -O0 anyway. Thanks to Anton Korobeynikov for pointing out the issue. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@288846 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
2 changed file(s) with 22 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
717717 .addReg(DestLo.getReg(), getKillRegState(DestLo.isDead()))
718718 .addOperand(DesiredLo)
719719 .addImm(0);
720 BuildMI(LoadCmpBB, DL, TII->get(AArch64::SBCSXr), AArch64::XZR)
720 BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg)
721 .addReg(AArch64::WZR)
722 .addReg(AArch64::WZR)
723 .addImm(AArch64CC::EQ);
724 BuildMI(LoadCmpBB, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
721725 .addReg(DestHi.getReg(), getKillRegState(DestHi.isDead()))
722 .addOperand(DesiredHi);
723 BuildMI(LoadCmpBB, DL, TII->get(AArch64::Bcc))
724 .addImm(AArch64CC::NE)
725 .addMBB(DoneBB)
726 .addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
726 .addOperand(DesiredHi)
727 .addImm(0);
728 BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg)
729 .addReg(StatusReg, RegState::Kill)
730 .addReg(StatusReg, RegState::Kill)
731 .addImm(AArch64CC::EQ);
732 BuildMI(LoadCmpBB, DL, TII->get(AArch64::CBNZW))
733 .addReg(StatusReg, RegState::Kill)
734 .addMBB(DoneBB);
727735 LoadCmpBB->addSuccessor(DoneBB);
728736 LoadCmpBB->addSuccessor(StoreBB);
729737
6464 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
6565 ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0]
6666 ; CHECK: cmp [[OLD_LO]], x2
67 ; CHECK: sbcs xzr, [[OLD_HI]], x3
68 ; CHECK: b.ne [[DONE:.LBB[0-9]+_[0-9]+]]
67 ; CHECK: cset [[CMP_TMP:w[0-9]+]], ne
68 ; CHECK: cmp [[OLD_HI]], x3
69 ; CHECK: cinc [[CMP:w[0-9]+]], [[CMP_TMP]], ne
70 ; CHECK: cbnz [[CMP]], [[DONE:.LBB[0-9]+_[0-9]+]]
6971 ; CHECK: stlxp [[STATUS:w[0-9]+]], x4, x5, [x0]
7072 ; CHECK: cbnz [[STATUS]], [[RETRY]]
7173 ; CHECK: [[DONE]]:
8789 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
8890 ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0]
8991 ; CHECK: cmp [[OLD_LO]], [[DESIRED_LO]]
90 ; CHECK: sbcs xzr, [[OLD_HI]], [[DESIRED_HI]]
91 ; CHECK: b.ne [[DONE:.LBB[0-9]+_[0-9]+]]
92 ; CHECK: cset [[CMP_TMP:w[0-9]+]], ne
93 ; CHECK: cmp [[OLD_HI]], [[DESIRED_HI]]
94 ; CHECK: cinc [[CMP:w[0-9]+]], [[CMP_TMP]], ne
95 ; CHECK: cbnz [[CMP]], [[DONE:.LBB[0-9]+_[0-9]+]]
9296 ; CHECK: stlxp [[STATUS:w[0-9]+]], [[NEW_LO]], [[NEW_HI]], [x0]
9397 ; CHECK: cbnz [[STATUS]], [[RETRY]]
9498 ; CHECK: [[DONE]]: