diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -408,46 +408,71 @@ bool IgnoreAlignment = false) { assert(I1->getOpcode() == I2->getOpcode() && "Can not compare special state of different instructions"); + assert(I1->getNumOperands() == I2->getNumOperands() && + "Can not compare special state of instructions with different number " + "of operands"); - if (const AllocaInst *AI = dyn_cast(I1)) + switch (I1->getOpcode()) { + default: + llvm_unreachable("Instructions to compare are unknown"); + case Instruction::Alloca: { + const AllocaInst *AI = cast(I1); return AI->getAllocatedType() == cast(I2)->getAllocatedType() && (AI->getAlignment() == cast(I2)->getAlignment() || IgnoreAlignment); - if (const LoadInst *LI = dyn_cast(I1)) + } + case Instruction::Load: { + const LoadInst *LI = cast(I1); return LI->isVolatile() == cast(I2)->isVolatile() && (LI->getAlignment() == cast(I2)->getAlignment() || IgnoreAlignment) && LI->getOrdering() == cast(I2)->getOrdering() && LI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const StoreInst *SI = dyn_cast(I1)) + } + case Instruction::Store: { + const StoreInst *SI = cast(I1); return SI->isVolatile() == cast(I2)->isVolatile() && (SI->getAlignment() == cast(I2)->getAlignment() || IgnoreAlignment) && SI->getOrdering() == cast(I2)->getOrdering() && SI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const CmpInst *CI = dyn_cast(I1)) - return CI->getPredicate() == cast(I2)->getPredicate(); - if (const CallInst *CI = dyn_cast(I1)) + } + case Instruction::ICmp: + case Instruction::FCmp: + return cast(I1)->getPredicate() == + cast(I2)->getPredicate(); + case Instruction::Call: { + const CallInst *CI = cast(I1); return CI->isTailCall() == cast(I2)->isTailCall() && CI->getCallingConv() == cast(I2)->getCallingConv() && CI->getAttributes() == cast(I2)->getAttributes() && CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const InvokeInst *CI = dyn_cast(I1)) - return CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes() && - CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const CallBrInst *CI = dyn_cast(I1)) - return CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes() && - CI->hasIdenticalOperandBundleSchema(*cast(I2)); - if (const InsertValueInst *IVI = dyn_cast(I1)) - return IVI->getIndices() == cast(I2)->getIndices(); - if (const ExtractValueInst *EVI = dyn_cast(I1)) - return EVI->getIndices() == cast(I2)->getIndices(); - if (const FenceInst *FI = dyn_cast(I1)) + } + case Instruction::Invoke: { + const InvokeInst *II = cast(I1); + return II->getCallingConv() == cast(I2)->getCallingConv() && + II->getAttributes() == cast(I2)->getAttributes() && + II->hasIdenticalOperandBundleSchema(*cast(I2)); + } + case Instruction::CallBr: { + const CallBrInst *CBI = cast(I1); + return CBI->getCallingConv() == cast(I2)->getCallingConv() && + CBI->getAttributes() == cast(I2)->getAttributes() && + CBI->hasIdenticalOperandBundleSchema(*cast(I2)); + } + case Instruction::InsertValue: + return cast(I1)->getIndices() == + cast(I2)->getIndices(); + case Instruction::ExtractValue: + return cast(I1)->getIndices() == + cast(I2)->getIndices(); + case Instruction::Fence: { + const FenceInst *FI = cast(I1); return FI->getOrdering() == cast(I2)->getOrdering() && FI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const AtomicCmpXchgInst *CXI = dyn_cast(I1)) + } + case Instruction::AtomicCmpXchg: { + const AtomicCmpXchgInst *CXI = cast(I1); return CXI->isVolatile() == cast(I2)->isVolatile() && CXI->isWeak() == cast(I2)->isWeak() && CXI->getSuccessOrdering() == @@ -456,16 +481,95 @@ cast(I2)->getFailureOrdering() && CXI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const AtomicRMWInst *RMWI = dyn_cast(I1)) + } + case Instruction::AtomicRMW: { + const AtomicRMWInst *RMWI = cast(I1); return RMWI->getOperation() == cast(I2)->getOperation() && RMWI->isVolatile() == cast(I2)->isVolatile() && RMWI->getOrdering() == cast(I2)->getOrdering() && RMWI->getSyncScopeID() == cast(I2)->getSyncScopeID(); - if (const ShuffleVectorInst *SVI = dyn_cast(I1)) - return SVI->getShuffleMask() == + } + case Instruction::ShuffleVector: + return cast(I1)->getShuffleMask() == cast(I2)->getShuffleMask(); - - return true; + case Instruction::Ret: + return true; + case Instruction::Br: + return true; + case Instruction::Switch: + return true; + case Instruction::IndirectBr: + return true; + case Instruction::Resume: + return true; + case Instruction::CatchSwitch: + return cast(I1)->unwindsToCaller() == + cast(I2)->unwindsToCaller(); + case Instruction::CatchRet: + return true; + case Instruction::CleanupRet: + return cast(I1)->unwindsToCaller() == + cast(I2)->unwindsToCaller(); + case Instruction::Unreachable: + return true; + case Instruction::FNeg: + return true; + case Instruction::Add: + case Instruction::FAdd: + case Instruction::Sub: + case Instruction::FSub: + case Instruction::Mul: + case Instruction::FMul: + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + return true; + case Instruction::GetElementPtr: + return true; + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + case Instruction::AddrSpaceCast: + return true; + case Instruction::CleanupPad: + return true; + case Instruction::CatchPad: + return haveSameSpecialState(cast(I1)->getCatchSwitch(), + cast(I2)->getCatchSwitch()); + case Instruction::PHI: + return true; + case Instruction::Select: + return true; + case Instruction::VAArg: + return true; + case Instruction::ExtractElement: + return true; + case Instruction::InsertElement: + return true; + case Instruction::LandingPad: + return cast(I1)->isCleanup() == + cast(I2)->isCleanup(); + case Instruction::Freeze: + return true; + } } bool Instruction::isIdenticalTo(const Instruction *I) const {