From b6d535b47e3f90751d1e3697a9cc240fc01b1314 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Mon, 21 Jul 2014 17:33:44 +0000 Subject: [PATCH] Replace the result usages while legalizing cmpxchg. We should update the usages to all of the results; otherwise, we might get assertion failure or SEGV during the type legalization of ATOMIC_CMP_SWAP_WITH_SUCCESS with two or more illegal types. For example, in the following sequence, both i8 and i1 might be illegal in some target, e.g. armv5, mipsel, mips64el, %0 = cmpxchg i8* %ptr, i8 %desire, i8 %new monotonic monotonic %1 = extractvalue { i8, i1 } %0, 1 Since both i8 and i1 should be legalized, the corresponding ATOMIC_CMP_SWAP_WITH_SUCCESS dag will be checked/replaced/updated twice. If we don't update the usage to *ALL* of the results in the first round, the DAG for extractvalue might be processed earlier. The GetPromotedInteger() will result in assertion failure, because its operand (i.e. the success bit of cmpxchg) is not promoted beforehand. llvm-svn: 213569 --- .../SelectionDAG/LegalizeIntegerTypes.cpp | 7 ++- test/CodeGen/ARM/atomic-cmpxchg.ll | 50 +++++++++++++++++++ test/CodeGen/Mips/atomic.ll | 46 ++++++++++++++++- 3 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/ARM/atomic-cmpxchg.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 484bcb7cccd..44d9e3875b8 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -225,10 +225,9 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N, N->getOpcode(), SDLoc(N), N->getMemoryVT(), VTs, N->getChain(), N->getBasePtr(), Op2, Op3, N->getMemOperand(), N->getSuccessOrdering(), N->getFailureOrdering(), N->getSynchScope()); - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - unsigned ChainOp = N->getNumValues() - 1; - ReplaceValueWith(SDValue(N, ChainOp), Res.getValue(ChainOp)); + // Update the use to N with the newly created Res. + for (unsigned i = 1, NumResults = N->getNumValues(); i < NumResults; ++i) + ReplaceValueWith(SDValue(N, i), Res.getValue(i)); return Res; } diff --git a/test/CodeGen/ARM/atomic-cmpxchg.ll b/test/CodeGen/ARM/atomic-cmpxchg.ll new file mode 100644 index 00000000000..4b79fa25145 --- /dev/null +++ b/test/CodeGen/ARM/atomic-cmpxchg.ll @@ -0,0 +1,50 @@ +; RUN: llc < %s -mtriple=arm-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-ARM +; RUN: llc < %s -mtriple=thumb-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-THUMB + +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-ARMV7 +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-THUMBV7 + +define zeroext i1 @test_cmpxchg_res_i8(i8* %addr, i8 %desired, i8 zeroext %new) { +entry: + %0 = cmpxchg i8* %addr, i8 %desired, i8 %new monotonic monotonic + %1 = extractvalue { i8, i1 } %0, 1 + ret i1 %1 +} + +; CHECK-ARM-LABEL: test_cmpxchg_res_i8 +; CHECK-ARM: bl __sync_val_compare_and_swap_1 +; CHECK-ARM: mov [[REG:r[0-9]+]], #0 +; CHECK-ARM: cmp r0, {{r[0-9]+}} +; CHECK-ARM: moveq [[REG]], #1 +; CHECK-ARM: mov r0, [[REG]] + +; CHECK-THUMB-LABEL: test_cmpxchg_res_i8 +; CHECK-THUMB: bl __sync_val_compare_and_swap_1 +; CHECK-THUMB: mov [[R1:r[0-9]+]], r0 +; CHECK-THUMB: movs r0, #1 +; CHECK-THUMB: movs [[R2:r[0-9]+]], #0 +; CHECK-THUMB: cmp [[R1]], {{r[0-9]+}} +; CHECK-THU