forked from OSchip/llvm-project
ARM: fix assertion failure on -O0 cmpxchg.
Because lowering of CMP_SWAP_64 occurs during type legalization, there can be i64 types produced by more than just a BUILD_PAIR or similar. My initial tests used just incoming function args. llvm-svn: 266828
This commit is contained in:
parent
50de4e8346
commit
1ee27c74cb
|
@ -6971,13 +6971,17 @@ static void ReplaceREADCYCLECOUNTER(SDNode *N,
|
|||
Results.push_back(Cycles32.getValue(1));
|
||||
}
|
||||
|
||||
static SDValue createGPRPairNode(SelectionDAG &DAG, SDValue V0, SDValue V1) {
|
||||
SDLoc dl(V0.getNode());
|
||||
static SDValue createGPRPairNode(SelectionDAG &DAG, SDValue V) {
|
||||
SDLoc dl(V.getNode());
|
||||
SDValue VLo = DAG.getAnyExtOrTrunc(V, dl, MVT::i32);
|
||||
SDValue VHi = DAG.getAnyExtOrTrunc(
|
||||
DAG.getNode(ISD::SRL, dl, MVT::i64, V, DAG.getConstant(32, dl, MVT::i32)),
|
||||
dl, MVT::i32);
|
||||
SDValue RegClass =
|
||||
DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
|
||||
SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
|
||||
SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||
const SDValue Ops[] = { RegClass, VLo, SubReg0, VHi, SubReg1 };
|
||||
return SDValue(
|
||||
DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
|
||||
}
|
||||
|
@ -6988,10 +6992,8 @@ static void ReplaceCMP_SWAP_64Results(SDNode *N,
|
|||
assert(N->getValueType(0) == MVT::i64 &&
|
||||
"AtomicCmpSwap on types less than 64 should be legal");
|
||||
SDValue Ops[] = {N->getOperand(1),
|
||||
createGPRPairNode(DAG, N->getOperand(2)->getOperand(0),
|
||||
N->getOperand(2)->getOperand(1)),
|
||||
createGPRPairNode(DAG, N->getOperand(3)->getOperand(0),
|
||||
N->getOperand(3)->getOperand(1)),
|
||||
createGPRPairNode(DAG, N->getOperand(2)),
|
||||
createGPRPairNode(DAG, N->getOperand(3)),
|
||||
N->getOperand(0)};
|
||||
SDNode *CmpSwap = DAG.getMachineNode(
|
||||
ARM::CMP_SWAP_64, SDLoc(N),
|
||||
|
|
|
@ -79,3 +79,24 @@ define { i64, i1 } @test_cmpxchg_64(i64* %addr, i64 %desired, i64 %new) nounwind
|
|||
%res = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst monotonic
|
||||
ret { i64, i1 } %res
|
||||
}
|
||||
|
||||
define { i64, i1 } @test_nontrivial_args(i64* %addr, i64 %desired, i64 %new) {
|
||||
; CHECK-LABEL: test_nontrivial_args:
|
||||
; CHECK: dmb ish
|
||||
; CHECK-NOT: uxt
|
||||
; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
|
||||
; CHECK: ldrexd [[OLDLO:r[0-9]+]], [[OLDHI:r[0-9]+]], [r0]
|
||||
; CHECK: cmp [[OLDLO]], {{r[0-9]+}}
|
||||
; CHECK: sbcs{{(\.w)?}} [[STATUS:r[0-9]+]], [[OLDHI]], {{r[0-9]+}}
|
||||
; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
|
||||
; CHECK: strexd [[STATUS]], {{r[0-9]+}}, {{r[0-9]+}}, [r0]
|
||||
; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
|
||||
; CHECK: bne [[RETRY]]
|
||||
; CHECK: [[DONE]]:
|
||||
; CHECK: dmb ish
|
||||
|
||||
%desired1 = add i64 %desired, 1
|
||||
%new1 = add i64 %new, 1
|
||||
%res = cmpxchg i64* %addr, i64 %desired1, i64 %new1 seq_cst seq_cst
|
||||
ret { i64, i1 } %res
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue