From 30582457b47004dec8a78144abc919a13ccbd08c Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Fri, 10 Jul 2020 04:27:39 +0000 Subject: [NFC] Separate bitcode reading for FUNC_CODE_INST_CMPXCHG(_OLD) This is preparatory work to unable storing alignment for AtomicCmpXchgInst. See D83136 for context and bug: https://bugs.llvm.org/show_bug.cgi?id=27168 Differential Revision: https://reviews.llvm.org/D83375 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 113 ++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 28 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 659e26c..ad1e975 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -4982,63 +4982,120 @@ Error BitcodeReader::parseFunctionBody(Function *F) { 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(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(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(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(I)->setVolatile(Record[OpNum]); - if (Record.size() < 8) { + cast(I)->setVolatile(IsVol); + + if (RecordCount > 7) { + cast(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(FullTy)->getElementType(0); - } else { - cast(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(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(I)->setVolatile(IsVol); + cast(I)->setWeak(IsWeak); InstructionList.push_back(I); break; -- cgit v1.1