From 8ead88dca1a54f3d36d1f484cc35600180abfa04 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 19 Apr 2016 22:25:02 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMISelLowering.cpp | 16 +++++++++------- test/CodeGen/ARM/cmpxchg-O0.ll | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index f240dca1b07..febe58b8fa7 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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), diff --git a/test/CodeGen/ARM/cmpxchg-O0.ll b/test/CodeGen/ARM/cmpxchg-O0.ll index 0bf22b05a76..c29050ed680 100644 --- a/test/CodeGen/ARM/cmpxchg-O0.ll +++ b/test/CodeGen/ARM/cmpxchg-O0.ll @@ -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 +}