FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
- FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
- // ordering, synchscope]
+ FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty, ptr, cmp, new, vol,
+ // success_ordering, ssid,
+ // failure_ordering?, weak?]
FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
// ordering, synchscope]
FUNC_CODE_INST_GEP = 43, // GEP: [inbounds, n x operands]
FUNC_CODE_INST_STORE = 44, // STORE: [ptrty,ptr,valty,val, align, vol]
FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol
- FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align,
- // vol,ordering,synchscope]
+ FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty, ptr, cmp, newval, vol,
+ // success_ordering, ssid,
+ // failure_ordering, weak]
FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#]
FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [val,bb#]
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CMPXCHG_OLD:
- case bitc::FUNC_CODE_INST_CMPXCHG: {
- // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, ssid,
+ case bitc::FUNC_CODE_INST_CMPXCHG_OLD: {
+ // CMPXCHG:[ptrty, ptr, cmp, new, vol, success_ordering, ssid,
// failureordering?, isweak?]
- unsigned OpNum = 0;
- Value *Ptr, *Cmp, *New;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
+ const size_t RecordCount = Record.size();
+ unsigned Slot = 0;
+ Value *Ptr = nullptr;
+ if (getValueTypePair(Record, Slot, NextValueNo, Ptr, &FullTy))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
return error("Cmpxchg operand is not a pointer type");
- if (BitCode == bitc::FUNC_CODE_INST_CMPXCHG) {
- if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy))
- return error("Invalid record");
- } else if (popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Cmp))
+ Value *Cmp = nullptr;
+ if (popValue(Record, Slot, NextValueNo, getPointerElementFlatType(FullTy),
+ Cmp))
return error("Invalid record");
- else
- FullTy = cast<PointerType>(FullTy)->getElementType();
- if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
- Record.size() < OpNum + 3 || Record.size() > OpNum + 5)
+ if (!(RecordCount == 6 || RecordCount == 7 || RecordCount == 8))
return error("Invalid record");
- AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[OpNum + 1]);
- if (SuccessOrdering == AtomicOrdering::NotAtomic ||
- SuccessOrdering == AtomicOrdering::Unordered)
+ Value *New = nullptr;
+ if (popValue(Record, Slot, NextValueNo, Cmp->getType(), New))
return error("Invalid record");
- SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType()))
return Err;
+
+ const bool IsVol = Record[3];
+
+ const AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[4]);
+ if (SuccessOrdering == AtomicOrdering::NotAtomic ||
+ SuccessOrdering == AtomicOrdering::Unordered)
+ return error("Invalid record");
+
+ const SyncScope::ID SSID = getDecodedSyncScopeID(Record[5]);
+
AtomicOrdering FailureOrdering;
- if (Record.size() < 7)
+ if (RecordCount > 6)
+ FailureOrdering = getDecodedOrdering(Record[6]);
+ else
FailureOrdering =
AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering);
- else
- FailureOrdering = getDecodedOrdering(Record[OpNum + 3]);
- Align Alignment(
+ const Align Alignment(
TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
+
+ FullTy = cast<PointerType>(FullTy)->getElementType();
+ FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
FailureOrdering, SSID);
- FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
- cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
- if (Record.size() < 8) {
+ cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
+
+ if (RecordCount > 7) {
+ cast<AtomicCmpXchgInst>(I)->setWeak(Record[7]);
+ } else {
// Before weak cmpxchgs existed, the instruction simply returned the
// value loaded from memory, so bitcode files from that era will be
// expecting the first component of a modern cmpxchg.
CurBB->getInstList().push_back(I);
I = ExtractValueInst::Create(I, 0);
FullTy = cast<StructType>(FullTy)->getElementType(0);
- } else {
- cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum+4]);
}
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CMPXCHG: {
+ // CMPXCHG: [ptrty, ptr, cmp, newval, vol, success_ordering, ssid,
+ // failure_ordering, weak]
+ const size_t RecordCount = Record.size();
+ unsigned Slot = 0;
+ Value *Ptr = nullptr;
+ if (getValueTypePair(Record, Slot, NextValueNo, Ptr, &FullTy))
+ return error("Invalid record");
+
+ if (!isa<PointerType>(Ptr->getType()))
+ return error("Cmpxchg operand is not a pointer type");
+
+ Value *Cmp = nullptr;
+ if (getValueTypePair(Record, Slot, NextValueNo, Cmp, &FullTy))
+ return error("Invalid record");
+
+ if (RecordCount != 8)
+ return error("Invalid record");
+
+ Value *New = nullptr;
+ if (popValue(Record, Slot, NextValueNo, Cmp->getType(), New))
+ return error("Invalid record");
+
+ const bool IsVol = Record[3];
+
+ const AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[4]);
+ if (SuccessOrdering == AtomicOrdering::NotAtomic ||
+ SuccessOrdering == AtomicOrdering::Unordered)
+ return error("Invalid record");
+
+ const SyncScope::ID SSID = getDecodedSyncScopeID(Record[5]);
+
+ if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType()))
+ return Err;
+
+ const AtomicOrdering FailureOrdering = getDecodedOrdering(Record[6]);
+
+ const bool IsWeak = Record[7];
+
+ const Align Alignment(
+ TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
+
+ FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
+ I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
+ FailureOrdering, SSID);
+
+ cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
+ cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak);
InstructionList.push_back(I);
break;