diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5143,6 +5143,10 @@ ? AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering) : getDecodedOrdering(Record[OpNum + 3]); + if (FailureOrdering == AtomicOrdering::NotAtomic || + FailureOrdering == AtomicOrdering::Unordered) + return error("Invalid record"); + const Align Alignment( TheModule->getDataLayout().getTypeStoreSize(Cmp->getType())); diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1560,6 +1560,10 @@ "AtomicCmpXchg instructions must be atomic!"); assert(FailureOrdering != AtomicOrdering::NotAtomic && "AtomicCmpXchg instructions must be atomic!"); + assert(SuccessOrdering != AtomicOrdering::Unordered && + "AtomicCmpXchg success ordering cannot be unordered"); + assert(FailureOrdering != AtomicOrdering::Unordered && + "AtomicCmpXchg failure ordering cannot be unordered"); assert(FailureOrdering != AtomicOrdering::Release && FailureOrdering != AtomicOrdering::AcquireRelease && "AtomicCmpXchg failure ordering cannot include release semantics"); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3831,29 +3831,7 @@ } void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) { - - // FIXME: more conditions??? - Assert(CXI.getSuccessOrdering() != AtomicOrdering::NotAtomic, - "cmpxchg instructions must be atomic.", &CXI); - Assert(CXI.getFailureOrdering() != AtomicOrdering::NotAtomic, - "cmpxchg instructions must be atomic.", &CXI); - Assert(CXI.getSuccessOrdering() != AtomicOrdering::Unordered, - "cmpxchg instructions cannot be unordered.", &CXI); - Assert(CXI.getFailureOrdering() != AtomicOrdering::Unordered, - "cmpxchg instructions cannot be unordered.", &CXI); - Assert(CXI.getFailureOrdering() != AtomicOrdering::Release && - CXI.getFailureOrdering() != AtomicOrdering::AcquireRelease, - "cmpxchg failure ordering cannot include release semantics", &CXI); - - PointerType *PTy = dyn_cast(CXI.getOperand(0)->getType()); - Assert(PTy, "First cmpxchg operand must be a pointer.", &CXI); Type *ElTy = CXI.getOperand(1)->getType(); - Assert(PTy->isOpaqueOrPointeeTypeMatches(ElTy), - "Expected value type does not match pointer operand type!", &CXI, - ElTy); - Assert(ElTy == CXI.getOperand(2)->getType(), - "Stored value type does not match expected value operand type!", &CXI, - ElTy); Assert(ElTy->isIntOrPtrTy(), "cmpxchg operand must have integer or pointer type", ElTy, &CXI); checkAtomicMemAccessSize(ElTy, &CXI); @@ -3861,13 +3839,9 @@ } void Verifier::visitAtomicRMWInst(AtomicRMWInst &RMWI) { - Assert(RMWI.getOrdering() != AtomicOrdering::NotAtomic, - "atomicrmw instructions must be atomic.", &RMWI); Assert(RMWI.getOrdering() != AtomicOrdering::Unordered, "atomicrmw instructions cannot be unordered.", &RMWI); auto Op = RMWI.getOperation(); - PointerType *PTy = dyn_cast(RMWI.getOperand(0)->getType()); - Assert(PTy, "First atomicrmw operand must be a pointer.", &RMWI); Type *ElTy = RMWI.getOperand(1)->getType(); if (Op == AtomicRMWInst::Xchg) { Assert(ElTy->isIntegerTy() || ElTy->isFloatingPointTy(), "atomicrmw " + @@ -3886,9 +3860,6 @@ &RMWI, ElTy); } checkAtomicMemAccessSize(ElTy, &RMWI); - Assert(PTy->isOpaqueOrPointeeTypeMatches(ElTy), - "Argument value type does not match pointer operand type!", &RMWI, - ElTy); Assert(AtomicRMWInst::FIRST_BINOP <= Op && Op <= AtomicRMWInst::LAST_BINOP, "Invalid binary operation!", &RMWI); visitInstruction(RMWI); diff --git a/llvm/test/Assembler/cmpxchg-ordering-2.ll b/llvm/test/Assembler/cmpxchg-ordering-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/cmpxchg-ordering-2.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +define void @f(i32* %a, i32 %b, i32 %c) { +; CHECK: cmpxchg cannot be unordered + %x = cmpxchg i32* %a, i32 %b, i32 %c acq_rel unordered + ret void +} diff --git a/llvm/test/Assembler/cmpxchg-ordering.ll b/llvm/test/Assembler/cmpxchg-ordering.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/cmpxchg-ordering.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +define void @f(i32* %a, i32 %b, i32 %c) { +; CHECK: cmpxchg cannot be unordered + %x = cmpxchg i32* %a, i32 %b, i32 %c unordered monotonic + ret void +}