10b57cec5SDimitry Andric //===- Instructions.cpp - Implement the LLVM instructions -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements all of the non-inline methods for the LLVM instruction 100b57cec5SDimitry Andric // classes. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 150b57cec5SDimitry Andric #include "LLVMContextImpl.h" 16bdd1243dSDimitry Andric #include "llvm/ADT/SmallBitVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 190b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 200b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 210b57cec5SDimitry Andric #include "llvm/IR/Constant.h" 22*0fca6ea1SDimitry Andric #include "llvm/IR/ConstantRange.h" 230b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 240b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 250b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 260b57cec5SDimitry Andric #include "llvm/IR/Function.h" 270b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h" 280b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 290b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 300b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 310b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 320b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 330b57cec5SDimitry Andric #include "llvm/IR/Module.h" 340b57cec5SDimitry Andric #include "llvm/IR/Operator.h" 35bdd1243dSDimitry Andric #include "llvm/IR/ProfDataUtils.h" 360b57cec5SDimitry Andric #include "llvm/IR/Type.h" 370b57cec5SDimitry Andric #include "llvm/IR/Value.h" 380b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h" 390b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 40*0fca6ea1SDimitry Andric #include "llvm/Support/CheckedArithmetic.h" 410b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 420b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 43bdd1243dSDimitry Andric #include "llvm/Support/ModRef.h" 448bcb0991SDimitry Andric #include "llvm/Support/TypeSize.h" 450b57cec5SDimitry Andric #include <algorithm> 460b57cec5SDimitry Andric #include <cassert> 470b57cec5SDimitry Andric #include <cstdint> 48bdd1243dSDimitry Andric #include <optional> 490b57cec5SDimitry Andric #include <vector> 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric using namespace llvm; 520b57cec5SDimitry Andric 53fe6060f1SDimitry Andric static cl::opt<bool> DisableI2pP2iOpt( 54fe6060f1SDimitry Andric "disable-i2p-p2i-opt", cl::init(false), 55fe6060f1SDimitry Andric cl::desc("Disables inttoptr/ptrtoint roundtrip optimization")); 56fe6060f1SDimitry Andric 570b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 580b57cec5SDimitry Andric // AllocaInst Class 590b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 600b57cec5SDimitry Andric 61bdd1243dSDimitry Andric std::optional<TypeSize> 62bdd1243dSDimitry Andric AllocaInst::getAllocationSize(const DataLayout &DL) const { 63bdd1243dSDimitry Andric TypeSize Size = DL.getTypeAllocSize(getAllocatedType()); 640b57cec5SDimitry Andric if (isArrayAllocation()) { 655ffd83dbSDimitry Andric auto *C = dyn_cast<ConstantInt>(getArraySize()); 660b57cec5SDimitry Andric if (!C) 67bdd1243dSDimitry Andric return std::nullopt; 68e8d8bef9SDimitry Andric assert(!Size.isScalable() && "Array elements cannot have a scalable size"); 69*0fca6ea1SDimitry Andric auto CheckedProd = 70*0fca6ea1SDimitry Andric checkedMulUnsigned(Size.getKnownMinValue(), C->getZExtValue()); 71*0fca6ea1SDimitry Andric if (!CheckedProd) 72*0fca6ea1SDimitry Andric return std::nullopt; 73*0fca6ea1SDimitry Andric return TypeSize::getFixed(*CheckedProd); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric return Size; 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 78bdd1243dSDimitry Andric std::optional<TypeSize> 79bdd1243dSDimitry Andric AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const { 80bdd1243dSDimitry Andric std::optional<TypeSize> Size = getAllocationSize(DL); 81*0fca6ea1SDimitry Andric if (!Size) 82bdd1243dSDimitry Andric return std::nullopt; 83*0fca6ea1SDimitry Andric auto CheckedProd = checkedMulUnsigned(Size->getKnownMinValue(), 84*0fca6ea1SDimitry Andric static_cast<TypeSize::ScalarTy>(8)); 85*0fca6ea1SDimitry Andric if (!CheckedProd) 86*0fca6ea1SDimitry Andric return std::nullopt; 87*0fca6ea1SDimitry Andric return TypeSize::get(*CheckedProd, Size->isScalable()); 88bdd1243dSDimitry Andric } 89bdd1243dSDimitry Andric 900b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 910b57cec5SDimitry Andric // SelectInst Class 920b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// areInvalidOperands - Return a string if the specified operands are invalid 950b57cec5SDimitry Andric /// for a select operation, otherwise return null. 960b57cec5SDimitry Andric const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { 970b57cec5SDimitry Andric if (Op1->getType() != Op2->getType()) 980b57cec5SDimitry Andric return "both values to select must have same type"; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric if (Op1->getType()->isTokenTy()) 1010b57cec5SDimitry Andric return "select values cannot have token type"; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric if (VectorType *VT = dyn_cast<VectorType>(Op0->getType())) { 1040b57cec5SDimitry Andric // Vector select. 1050b57cec5SDimitry Andric if (VT->getElementType() != Type::getInt1Ty(Op0->getContext())) 1060b57cec5SDimitry Andric return "vector select condition element type must be i1"; 1070b57cec5SDimitry Andric VectorType *ET = dyn_cast<VectorType>(Op1->getType()); 1080b57cec5SDimitry Andric if (!ET) 1090b57cec5SDimitry Andric return "selected values for vector select must be vectors"; 1105ffd83dbSDimitry Andric if (ET->getElementCount() != VT->getElementCount()) 1110b57cec5SDimitry Andric return "vector select requires selected vectors to have " 1120b57cec5SDimitry Andric "the same vector length as select condition"; 1130b57cec5SDimitry Andric } else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) { 1140b57cec5SDimitry Andric return "select condition must be i1 or <n x i1>"; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric return nullptr; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1200b57cec5SDimitry Andric // PHINode Class 1210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric PHINode::PHINode(const PHINode &PN) 1240b57cec5SDimitry Andric : Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()), 1250b57cec5SDimitry Andric ReservedSpace(PN.getNumOperands()) { 1260b57cec5SDimitry Andric allocHungoffUses(PN.getNumOperands()); 1270b57cec5SDimitry Andric std::copy(PN.op_begin(), PN.op_end(), op_begin()); 128bdd1243dSDimitry Andric copyIncomingBlocks(make_range(PN.block_begin(), PN.block_end())); 1290b57cec5SDimitry Andric SubclassOptionalData = PN.SubclassOptionalData; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // removeIncomingValue - Remove an incoming value. This is useful if a 1330b57cec5SDimitry Andric // predecessor basic block is deleted. 1340b57cec5SDimitry Andric Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { 1350b57cec5SDimitry Andric Value *Removed = getIncomingValue(Idx); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric // Move everything after this operand down. 1380b57cec5SDimitry Andric // 1390b57cec5SDimitry Andric // FIXME: we could just swap with the end of the list, then erase. However, 1400b57cec5SDimitry Andric // clients might not expect this to happen. The code as it is thrashes the 1410b57cec5SDimitry Andric // use/def lists, which is kinda lame. 1420b57cec5SDimitry Andric std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); 1435f757f3fSDimitry Andric copyIncomingBlocks(drop_begin(blocks(), Idx + 1), Idx); 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric // Nuke the last value. 1460b57cec5SDimitry Andric Op<-1>().set(nullptr); 1470b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() - 1); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric // If the PHI node is dead, because it has zero entries, nuke it now. 1500b57cec5SDimitry Andric if (getNumOperands() == 0 && DeletePHIIfEmpty) { 1510b57cec5SDimitry Andric // If anyone is using this PHI, make them use a dummy value instead... 15281ad6265SDimitry Andric replaceAllUsesWith(PoisonValue::get(getType())); 1530b57cec5SDimitry Andric eraseFromParent(); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric return Removed; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1585f757f3fSDimitry Andric void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate, 1595f757f3fSDimitry Andric bool DeletePHIIfEmpty) { 1605f757f3fSDimitry Andric SmallDenseSet<unsigned> RemoveIndices; 1615f757f3fSDimitry Andric for (unsigned Idx = 0; Idx < getNumIncomingValues(); ++Idx) 1625f757f3fSDimitry Andric if (Predicate(Idx)) 1635f757f3fSDimitry Andric RemoveIndices.insert(Idx); 1645f757f3fSDimitry Andric 1655f757f3fSDimitry Andric if (RemoveIndices.empty()) 1665f757f3fSDimitry Andric return; 1675f757f3fSDimitry Andric 1685f757f3fSDimitry Andric // Remove operands. 1695f757f3fSDimitry Andric auto NewOpEnd = remove_if(operands(), [&](Use &U) { 1705f757f3fSDimitry Andric return RemoveIndices.contains(U.getOperandNo()); 1715f757f3fSDimitry Andric }); 1725f757f3fSDimitry Andric for (Use &U : make_range(NewOpEnd, op_end())) 1735f757f3fSDimitry Andric U.set(nullptr); 1745f757f3fSDimitry Andric 1755f757f3fSDimitry Andric // Remove incoming blocks. 1765f757f3fSDimitry Andric (void)std::remove_if(const_cast<block_iterator>(block_begin()), 1775f757f3fSDimitry Andric const_cast<block_iterator>(block_end()), [&](BasicBlock *&BB) { 1785f757f3fSDimitry Andric return RemoveIndices.contains(&BB - block_begin()); 1795f757f3fSDimitry Andric }); 1805f757f3fSDimitry Andric 1815f757f3fSDimitry Andric setNumHungOffUseOperands(getNumOperands() - RemoveIndices.size()); 1825f757f3fSDimitry Andric 1835f757f3fSDimitry Andric // If the PHI node is dead, because it has zero entries, nuke it now. 1845f757f3fSDimitry Andric if (getNumOperands() == 0 && DeletePHIIfEmpty) { 1855f757f3fSDimitry Andric // If anyone is using this PHI, make them use a dummy value instead... 1865f757f3fSDimitry Andric replaceAllUsesWith(PoisonValue::get(getType())); 1875f757f3fSDimitry Andric eraseFromParent(); 1885f757f3fSDimitry Andric } 1895f757f3fSDimitry Andric } 1905f757f3fSDimitry Andric 1910b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response 1920b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 1.5 1930b57cec5SDimitry Andric /// times. 1940b57cec5SDimitry Andric /// 1950b57cec5SDimitry Andric void PHINode::growOperands() { 1960b57cec5SDimitry Andric unsigned e = getNumOperands(); 1970b57cec5SDimitry Andric unsigned NumOps = e + e / 2; 1980b57cec5SDimitry Andric if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric ReservedSpace = NumOps; 2010b57cec5SDimitry Andric growHungoffUses(ReservedSpace, /* IsPhi */ true); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric /// hasConstantValue - If the specified PHI node always merges together the same 2050b57cec5SDimitry Andric /// value, return the value, otherwise return null. 2060b57cec5SDimitry Andric Value *PHINode::hasConstantValue() const { 2070b57cec5SDimitry Andric // Exploit the fact that phi nodes always have at least one entry. 2080b57cec5SDimitry Andric Value *ConstantValue = getIncomingValue(0); 2090b57cec5SDimitry Andric for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i) 2100b57cec5SDimitry Andric if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) { 2110b57cec5SDimitry Andric if (ConstantValue != this) 2120b57cec5SDimitry Andric return nullptr; // Incoming values not all the same. 2130b57cec5SDimitry Andric // The case where the first value is this PHI. 2140b57cec5SDimitry Andric ConstantValue = getIncomingValue(i); 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric if (ConstantValue == this) 217*0fca6ea1SDimitry Andric return PoisonValue::get(getType()); 2180b57cec5SDimitry Andric return ConstantValue; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric /// hasConstantOrUndefValue - Whether the specified PHI node always merges 2220b57cec5SDimitry Andric /// together the same value, assuming that undefs result in the same value as 2230b57cec5SDimitry Andric /// non-undefs. 2240b57cec5SDimitry Andric /// Unlike \ref hasConstantValue, this does not return a value because the 2250b57cec5SDimitry Andric /// unique non-undef incoming value need not dominate the PHI node. 2260b57cec5SDimitry Andric bool PHINode::hasConstantOrUndefValue() const { 2270b57cec5SDimitry Andric Value *ConstantValue = nullptr; 2280b57cec5SDimitry Andric for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i) { 2290b57cec5SDimitry Andric Value *Incoming = getIncomingValue(i); 2300b57cec5SDimitry Andric if (Incoming != this && !isa<UndefValue>(Incoming)) { 2310b57cec5SDimitry Andric if (ConstantValue && ConstantValue != Incoming) 2320b57cec5SDimitry Andric return false; 2330b57cec5SDimitry Andric ConstantValue = Incoming; 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric return true; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2400b57cec5SDimitry Andric // LandingPadInst Implementation 2410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues, 244*0fca6ea1SDimitry Andric const Twine &NameStr, 245*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 2460b57cec5SDimitry Andric : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) { 2470b57cec5SDimitry Andric init(NumReservedValues, NameStr); 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric LandingPadInst::LandingPadInst(const LandingPadInst &LP) 2510b57cec5SDimitry Andric : Instruction(LP.getType(), Instruction::LandingPad, nullptr, 2520b57cec5SDimitry Andric LP.getNumOperands()), 2530b57cec5SDimitry Andric ReservedSpace(LP.getNumOperands()) { 2540b57cec5SDimitry Andric allocHungoffUses(LP.getNumOperands()); 2550b57cec5SDimitry Andric Use *OL = getOperandList(); 2560b57cec5SDimitry Andric const Use *InOL = LP.getOperandList(); 2570b57cec5SDimitry Andric for (unsigned I = 0, E = ReservedSpace; I != E; ++I) 2580b57cec5SDimitry Andric OL[I] = InOL[I]; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric setCleanup(LP.isCleanup()); 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses, 2640b57cec5SDimitry Andric const Twine &NameStr, 265*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 2660b57cec5SDimitry Andric return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertBefore); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric void LandingPadInst::init(unsigned NumReservedValues, const Twine &NameStr) { 2700b57cec5SDimitry Andric ReservedSpace = NumReservedValues; 2710b57cec5SDimitry Andric setNumHungOffUseOperands(0); 2720b57cec5SDimitry Andric allocHungoffUses(ReservedSpace); 2730b57cec5SDimitry Andric setName(NameStr); 2740b57cec5SDimitry Andric setCleanup(false); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response to a 2780b57cec5SDimitry Andric /// push_back style of operation. This grows the number of ops by 2 times. 2790b57cec5SDimitry Andric void LandingPadInst::growOperands(unsigned Size) { 2800b57cec5SDimitry Andric unsigned e = getNumOperands(); 2810b57cec5SDimitry Andric if (ReservedSpace >= e + Size) return; 2820b57cec5SDimitry Andric ReservedSpace = (std::max(e, 1U) + Size / 2) * 2; 2830b57cec5SDimitry Andric growHungoffUses(ReservedSpace); 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric void LandingPadInst::addClause(Constant *Val) { 2870b57cec5SDimitry Andric unsigned OpNo = getNumOperands(); 2880b57cec5SDimitry Andric growOperands(1); 2890b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!"); 2900b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() + 1); 2910b57cec5SDimitry Andric getOperandList()[OpNo] = Val; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2950b57cec5SDimitry Andric // CallBase Implementation 2960b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2970b57cec5SDimitry Andric 2985ffd83dbSDimitry Andric CallBase *CallBase::Create(CallBase *CB, ArrayRef<OperandBundleDef> Bundles, 299*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 3005ffd83dbSDimitry Andric switch (CB->getOpcode()) { 3015ffd83dbSDimitry Andric case Instruction::Call: 3025ffd83dbSDimitry Andric return CallInst::Create(cast<CallInst>(CB), Bundles, InsertPt); 3035ffd83dbSDimitry Andric case Instruction::Invoke: 3045ffd83dbSDimitry Andric return InvokeInst::Create(cast<InvokeInst>(CB), Bundles, InsertPt); 3055ffd83dbSDimitry Andric case Instruction::CallBr: 3065ffd83dbSDimitry Andric return CallBrInst::Create(cast<CallBrInst>(CB), Bundles, InsertPt); 3075ffd83dbSDimitry Andric default: 3085ffd83dbSDimitry Andric llvm_unreachable("Unknown CallBase sub-class!"); 3095ffd83dbSDimitry Andric } 3105ffd83dbSDimitry Andric } 3115ffd83dbSDimitry Andric 312fe6060f1SDimitry Andric CallBase *CallBase::Create(CallBase *CI, OperandBundleDef OpB, 313*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 314fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 2> OpDefs; 315fe6060f1SDimitry Andric for (unsigned i = 0, e = CI->getNumOperandBundles(); i < e; ++i) { 316fe6060f1SDimitry Andric auto ChildOB = CI->getOperandBundleAt(i); 317fe6060f1SDimitry Andric if (ChildOB.getTagName() != OpB.getTag()) 318fe6060f1SDimitry Andric OpDefs.emplace_back(ChildOB); 319fe6060f1SDimitry Andric } 320fe6060f1SDimitry Andric OpDefs.emplace_back(OpB); 321fe6060f1SDimitry Andric return CallBase::Create(CI, OpDefs, InsertPt); 322fe6060f1SDimitry Andric } 323fe6060f1SDimitry Andric 3240b57cec5SDimitry Andric Function *CallBase::getCaller() { return getParent()->getParent(); } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric unsigned CallBase::getNumSubclassExtraOperandsDynamic() const { 3270b57cec5SDimitry Andric assert(getOpcode() == Instruction::CallBr && "Unexpected opcode!"); 3280b57cec5SDimitry Andric return cast<CallBrInst>(this)->getNumIndirectDests() + 1; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric bool CallBase::isIndirectCall() const { 3325ffd83dbSDimitry Andric const Value *V = getCalledOperand(); 3330b57cec5SDimitry Andric if (isa<Function>(V) || isa<Constant>(V)) 3340b57cec5SDimitry Andric return false; 3355ffd83dbSDimitry Andric return !isInlineAsm(); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric /// Tests if this call site must be tail call optimized. Only a CallInst can 3390b57cec5SDimitry Andric /// be tail call optimized. 3400b57cec5SDimitry Andric bool CallBase::isMustTailCall() const { 3410b57cec5SDimitry Andric if (auto *CI = dyn_cast<CallInst>(this)) 3420b57cec5SDimitry Andric return CI->isMustTailCall(); 3430b57cec5SDimitry Andric return false; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric /// Tests if this call site is marked as a tail call. 3470b57cec5SDimitry Andric bool CallBase::isTailCall() const { 3480b57cec5SDimitry Andric if (auto *CI = dyn_cast<CallInst>(this)) 3490b57cec5SDimitry Andric return CI->isTailCall(); 3500b57cec5SDimitry Andric return false; 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric Intrinsic::ID CallBase::getIntrinsicID() const { 3540b57cec5SDimitry Andric if (auto *F = getCalledFunction()) 3550b57cec5SDimitry Andric return F->getIntrinsicID(); 3560b57cec5SDimitry Andric return Intrinsic::not_intrinsic; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 35906c3fb27SDimitry Andric FPClassTest CallBase::getRetNoFPClass() const { 36006c3fb27SDimitry Andric FPClassTest Mask = Attrs.getRetNoFPClass(); 36106c3fb27SDimitry Andric 36206c3fb27SDimitry Andric if (const Function *F = getCalledFunction()) 36306c3fb27SDimitry Andric Mask |= F->getAttributes().getRetNoFPClass(); 36406c3fb27SDimitry Andric return Mask; 36506c3fb27SDimitry Andric } 36606c3fb27SDimitry Andric 36706c3fb27SDimitry Andric FPClassTest CallBase::getParamNoFPClass(unsigned i) const { 36806c3fb27SDimitry Andric FPClassTest Mask = Attrs.getParamNoFPClass(i); 36906c3fb27SDimitry Andric 37006c3fb27SDimitry Andric if (const Function *F = getCalledFunction()) 37106c3fb27SDimitry Andric Mask |= F->getAttributes().getParamNoFPClass(i); 37206c3fb27SDimitry Andric return Mask; 37306c3fb27SDimitry Andric } 37406c3fb27SDimitry Andric 375*0fca6ea1SDimitry Andric std::optional<ConstantRange> CallBase::getRange() const { 376*0fca6ea1SDimitry Andric const Attribute RangeAttr = getRetAttr(llvm::Attribute::Range); 377*0fca6ea1SDimitry Andric if (RangeAttr.isValid()) 378*0fca6ea1SDimitry Andric return RangeAttr.getRange(); 379*0fca6ea1SDimitry Andric return std::nullopt; 380*0fca6ea1SDimitry Andric } 381*0fca6ea1SDimitry Andric 3820b57cec5SDimitry Andric bool CallBase::isReturnNonNull() const { 3830b57cec5SDimitry Andric if (hasRetAttr(Attribute::NonNull)) 3840b57cec5SDimitry Andric return true; 3850b57cec5SDimitry Andric 386349cc55cSDimitry Andric if (getRetDereferenceableBytes() > 0 && 387349cc55cSDimitry Andric !NullPointerIsDefined(getCaller(), getType()->getPointerAddressSpace())) 3880b57cec5SDimitry Andric return true; 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric return false; 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 39381ad6265SDimitry Andric Value *CallBase::getArgOperandWithAttribute(Attribute::AttrKind Kind) const { 3940b57cec5SDimitry Andric unsigned Index; 3950b57cec5SDimitry Andric 39681ad6265SDimitry Andric if (Attrs.hasAttrSomewhere(Kind, &Index)) 3970b57cec5SDimitry Andric return getArgOperand(Index - AttributeList::FirstArgIndex); 3980b57cec5SDimitry Andric if (const Function *F = getCalledFunction()) 39981ad6265SDimitry Andric if (F->getAttributes().hasAttrSomewhere(Kind, &Index)) 4000b57cec5SDimitry Andric return getArgOperand(Index - AttributeList::FirstArgIndex); 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric return nullptr; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// Determine whether the argument or parameter has the given attribute. 4060b57cec5SDimitry Andric bool CallBase::paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { 407349cc55cSDimitry Andric assert(ArgNo < arg_size() && "Param index out of bounds!"); 4080b57cec5SDimitry Andric 409349cc55cSDimitry Andric if (Attrs.hasParamAttr(ArgNo, Kind)) 4100b57cec5SDimitry Andric return true; 411bdd1243dSDimitry Andric 412bdd1243dSDimitry Andric const Function *F = getCalledFunction(); 413bdd1243dSDimitry Andric if (!F) 4140b57cec5SDimitry Andric return false; 415bdd1243dSDimitry Andric 416bdd1243dSDimitry Andric if (!F->getAttributes().hasParamAttr(ArgNo, Kind)) 417bdd1243dSDimitry Andric return false; 418bdd1243dSDimitry Andric 419bdd1243dSDimitry Andric // Take into account mod/ref by operand bundles. 420bdd1243dSDimitry Andric switch (Kind) { 421bdd1243dSDimitry Andric case Attribute::ReadNone: 422bdd1243dSDimitry Andric return !hasReadingOperandBundles() && !hasClobberingOperandBundles(); 423bdd1243dSDimitry Andric case Attribute::ReadOnly: 424bdd1243dSDimitry Andric return !hasClobberingOperandBundles(); 425bdd1243dSDimitry Andric case Attribute::WriteOnly: 426bdd1243dSDimitry Andric return !hasReadingOperandBundles(); 427bdd1243dSDimitry Andric default: 428bdd1243dSDimitry Andric return true; 429bdd1243dSDimitry Andric } 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric bool CallBase::hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const { 433*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand())) 434349cc55cSDimitry Andric return F->getAttributes().hasFnAttr(Kind); 435349cc55cSDimitry Andric 4360b57cec5SDimitry Andric return false; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric bool CallBase::hasFnAttrOnCalledFunction(StringRef Kind) const { 440*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand())) 441349cc55cSDimitry Andric return F->getAttributes().hasFnAttr(Kind); 442349cc55cSDimitry Andric 4430b57cec5SDimitry Andric return false; 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric 44681ad6265SDimitry Andric template <typename AK> 44781ad6265SDimitry Andric Attribute CallBase::getFnAttrOnCalledFunction(AK Kind) const { 448bdd1243dSDimitry Andric if constexpr (std::is_same_v<AK, Attribute::AttrKind>) { 449bdd1243dSDimitry Andric // getMemoryEffects() correctly combines memory effects from the call-site, 450bdd1243dSDimitry Andric // operand bundles and function. 451bdd1243dSDimitry Andric assert(Kind != Attribute::Memory && "Use getMemoryEffects() instead"); 452bdd1243dSDimitry Andric } 453bdd1243dSDimitry Andric 454*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand())) 45581ad6265SDimitry Andric return F->getAttributes().getFnAttr(Kind); 45681ad6265SDimitry Andric 45781ad6265SDimitry Andric return Attribute(); 45881ad6265SDimitry Andric } 45981ad6265SDimitry Andric 46081ad6265SDimitry Andric template Attribute 46181ad6265SDimitry Andric CallBase::getFnAttrOnCalledFunction(Attribute::AttrKind Kind) const; 46281ad6265SDimitry Andric template Attribute CallBase::getFnAttrOnCalledFunction(StringRef Kind) const; 46381ad6265SDimitry Andric 464*0fca6ea1SDimitry Andric template <typename AK> 465*0fca6ea1SDimitry Andric Attribute CallBase::getParamAttrOnCalledFunction(unsigned ArgNo, 466*0fca6ea1SDimitry Andric AK Kind) const { 467*0fca6ea1SDimitry Andric Value *V = getCalledOperand(); 468*0fca6ea1SDimitry Andric 469*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(V)) 470*0fca6ea1SDimitry Andric return F->getAttributes().getParamAttr(ArgNo, Kind); 471*0fca6ea1SDimitry Andric 472*0fca6ea1SDimitry Andric return Attribute(); 473*0fca6ea1SDimitry Andric } 474*0fca6ea1SDimitry Andric template Attribute 475*0fca6ea1SDimitry Andric CallBase::getParamAttrOnCalledFunction(unsigned ArgNo, 476*0fca6ea1SDimitry Andric Attribute::AttrKind Kind) const; 477*0fca6ea1SDimitry Andric template Attribute CallBase::getParamAttrOnCalledFunction(unsigned ArgNo, 478*0fca6ea1SDimitry Andric StringRef Kind) const; 479*0fca6ea1SDimitry Andric 4805ffd83dbSDimitry Andric void CallBase::getOperandBundlesAsDefs( 4815ffd83dbSDimitry Andric SmallVectorImpl<OperandBundleDef> &Defs) const { 4825ffd83dbSDimitry Andric for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) 4835ffd83dbSDimitry Andric Defs.emplace_back(getOperandBundleAt(i)); 4845ffd83dbSDimitry Andric } 4855ffd83dbSDimitry Andric 4860b57cec5SDimitry Andric CallBase::op_iterator 4870b57cec5SDimitry Andric CallBase::populateBundleOperandInfos(ArrayRef<OperandBundleDef> Bundles, 4880b57cec5SDimitry Andric const unsigned BeginIndex) { 4890b57cec5SDimitry Andric auto It = op_begin() + BeginIndex; 4900b57cec5SDimitry Andric for (auto &B : Bundles) 4910b57cec5SDimitry Andric It = std::copy(B.input_begin(), B.input_end(), It); 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric auto *ContextImpl = getContext().pImpl; 4940b57cec5SDimitry Andric auto BI = Bundles.begin(); 4950b57cec5SDimitry Andric unsigned CurrentIndex = BeginIndex; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric for (auto &BOI : bundle_op_infos()) { 4980b57cec5SDimitry Andric assert(BI != Bundles.end() && "Incorrect allocation?"); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->getTag()); 5010b57cec5SDimitry Andric BOI.Begin = CurrentIndex; 5020b57cec5SDimitry Andric BOI.End = CurrentIndex + BI->input_size(); 5030b57cec5SDimitry Andric CurrentIndex = BOI.End; 5040b57cec5SDimitry Andric BI++; 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric assert(BI == Bundles.end() && "Incorrect allocation?"); 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric return It; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5125ffd83dbSDimitry Andric CallBase::BundleOpInfo &CallBase::getBundleOpInfoForOperand(unsigned OpIdx) { 5135ffd83dbSDimitry Andric /// When there isn't many bundles, we do a simple linear search. 5145ffd83dbSDimitry Andric /// Else fallback to a binary-search that use the fact that bundles usually 5155ffd83dbSDimitry Andric /// have similar number of argument to get faster convergence. 5165ffd83dbSDimitry Andric if (bundle_op_info_end() - bundle_op_info_begin() < 8) { 5175ffd83dbSDimitry Andric for (auto &BOI : bundle_op_infos()) 5185ffd83dbSDimitry Andric if (BOI.Begin <= OpIdx && OpIdx < BOI.End) 5195ffd83dbSDimitry Andric return BOI; 5205ffd83dbSDimitry Andric 5215ffd83dbSDimitry Andric llvm_unreachable("Did not find operand bundle for operand!"); 5225ffd83dbSDimitry Andric } 5235ffd83dbSDimitry Andric 5245ffd83dbSDimitry Andric assert(OpIdx >= arg_size() && "the Idx is not in the operand bundles"); 5255ffd83dbSDimitry Andric assert(bundle_op_info_end() - bundle_op_info_begin() > 0 && 5265ffd83dbSDimitry Andric OpIdx < std::prev(bundle_op_info_end())->End && 5275ffd83dbSDimitry Andric "The Idx isn't in the operand bundle"); 5285ffd83dbSDimitry Andric 5295ffd83dbSDimitry Andric /// We need a decimal number below and to prevent using floating point numbers 5305ffd83dbSDimitry Andric /// we use an intergal value multiplied by this constant. 5315ffd83dbSDimitry Andric constexpr unsigned NumberScaling = 1024; 5325ffd83dbSDimitry Andric 5335ffd83dbSDimitry Andric bundle_op_iterator Begin = bundle_op_info_begin(); 5345ffd83dbSDimitry Andric bundle_op_iterator End = bundle_op_info_end(); 535e8d8bef9SDimitry Andric bundle_op_iterator Current = Begin; 5365ffd83dbSDimitry Andric 5375ffd83dbSDimitry Andric while (Begin != End) { 5385ffd83dbSDimitry Andric unsigned ScaledOperandPerBundle = 5395ffd83dbSDimitry Andric NumberScaling * (std::prev(End)->End - Begin->Begin) / (End - Begin); 5405ffd83dbSDimitry Andric Current = Begin + (((OpIdx - Begin->Begin) * NumberScaling) / 5415ffd83dbSDimitry Andric ScaledOperandPerBundle); 5425ffd83dbSDimitry Andric if (Current >= End) 5435ffd83dbSDimitry Andric Current = std::prev(End); 5445ffd83dbSDimitry Andric assert(Current < End && Current >= Begin && 5455ffd83dbSDimitry Andric "the operand bundle doesn't cover every value in the range"); 5465ffd83dbSDimitry Andric if (OpIdx >= Current->Begin && OpIdx < Current->End) 5475ffd83dbSDimitry Andric break; 5485ffd83dbSDimitry Andric if (OpIdx >= Current->End) 5495ffd83dbSDimitry Andric Begin = Current + 1; 5505ffd83dbSDimitry Andric else 5515ffd83dbSDimitry Andric End = Current; 5525ffd83dbSDimitry Andric } 5535ffd83dbSDimitry Andric 5545ffd83dbSDimitry Andric assert(OpIdx >= Current->Begin && OpIdx < Current->End && 5555ffd83dbSDimitry Andric "the operand bundle doesn't cover every value in the range"); 5565ffd83dbSDimitry Andric return *Current; 5575ffd83dbSDimitry Andric } 5585ffd83dbSDimitry Andric 559fe6060f1SDimitry Andric CallBase *CallBase::addOperandBundle(CallBase *CB, uint32_t ID, 560fe6060f1SDimitry Andric OperandBundleDef OB, 561*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 562fe6060f1SDimitry Andric if (CB->getOperandBundle(ID)) 563fe6060f1SDimitry Andric return CB; 564fe6060f1SDimitry Andric 565fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 1> Bundles; 566fe6060f1SDimitry Andric CB->getOperandBundlesAsDefs(Bundles); 567fe6060f1SDimitry Andric Bundles.push_back(OB); 568fe6060f1SDimitry Andric return Create(CB, Bundles, InsertPt); 569fe6060f1SDimitry Andric } 570fe6060f1SDimitry Andric 571fe6060f1SDimitry Andric CallBase *CallBase::removeOperandBundle(CallBase *CB, uint32_t ID, 572*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 573fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 1> Bundles; 574fe6060f1SDimitry Andric bool CreateNew = false; 575fe6060f1SDimitry Andric 576fe6060f1SDimitry Andric for (unsigned I = 0, E = CB->getNumOperandBundles(); I != E; ++I) { 577fe6060f1SDimitry Andric auto Bundle = CB->getOperandBundleAt(I); 578fe6060f1SDimitry Andric if (Bundle.getTagID() == ID) { 579fe6060f1SDimitry Andric CreateNew = true; 580fe6060f1SDimitry Andric continue; 581fe6060f1SDimitry Andric } 582fe6060f1SDimitry Andric Bundles.emplace_back(Bundle); 583fe6060f1SDimitry Andric } 584fe6060f1SDimitry Andric 585fe6060f1SDimitry Andric return CreateNew ? Create(CB, Bundles, InsertPt) : CB; 586fe6060f1SDimitry Andric } 587fe6060f1SDimitry Andric 588fe6060f1SDimitry Andric bool CallBase::hasReadingOperandBundles() const { 589fe6060f1SDimitry Andric // Implementation note: this is a conservative implementation of operand 59081ad6265SDimitry Andric // bundle semantics, where *any* non-assume operand bundle (other than 59181ad6265SDimitry Andric // ptrauth) forces a callsite to be at least readonly. 592bdd1243dSDimitry Andric return hasOperandBundlesOtherThan( 593bdd1243dSDimitry Andric {LLVMContext::OB_ptrauth, LLVMContext::OB_kcfi}) && 59481ad6265SDimitry Andric getIntrinsicID() != Intrinsic::assume; 595fe6060f1SDimitry Andric } 596fe6060f1SDimitry Andric 597bdd1243dSDimitry Andric bool CallBase::hasClobberingOperandBundles() const { 598bdd1243dSDimitry Andric return hasOperandBundlesOtherThan( 599bdd1243dSDimitry Andric {LLVMContext::OB_deopt, LLVMContext::OB_funclet, 600bdd1243dSDimitry Andric LLVMContext::OB_ptrauth, LLVMContext::OB_kcfi}) && 601bdd1243dSDimitry Andric getIntrinsicID() != Intrinsic::assume; 602bdd1243dSDimitry Andric } 603bdd1243dSDimitry Andric 604bdd1243dSDimitry Andric MemoryEffects CallBase::getMemoryEffects() const { 605bdd1243dSDimitry Andric MemoryEffects ME = getAttributes().getMemoryEffects(); 606bdd1243dSDimitry Andric if (auto *Fn = dyn_cast<Function>(getCalledOperand())) { 607bdd1243dSDimitry Andric MemoryEffects FnME = Fn->getMemoryEffects(); 608bdd1243dSDimitry Andric if (hasOperandBundles()) { 609bdd1243dSDimitry Andric // TODO: Add a method to get memory effects for operand bundles instead. 610bdd1243dSDimitry Andric if (hasReadingOperandBundles()) 611bdd1243dSDimitry Andric FnME |= MemoryEffects::readOnly(); 612bdd1243dSDimitry Andric if (hasClobberingOperandBundles()) 613bdd1243dSDimitry Andric FnME |= MemoryEffects::writeOnly(); 614bdd1243dSDimitry Andric } 615bdd1243dSDimitry Andric ME &= FnME; 616bdd1243dSDimitry Andric } 617bdd1243dSDimitry Andric return ME; 618bdd1243dSDimitry Andric } 619bdd1243dSDimitry Andric void CallBase::setMemoryEffects(MemoryEffects ME) { 620bdd1243dSDimitry Andric addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME)); 621bdd1243dSDimitry Andric } 622bdd1243dSDimitry Andric 623bdd1243dSDimitry Andric /// Determine if the function does not access memory. 624bdd1243dSDimitry Andric bool CallBase::doesNotAccessMemory() const { 625bdd1243dSDimitry Andric return getMemoryEffects().doesNotAccessMemory(); 626bdd1243dSDimitry Andric } 627bdd1243dSDimitry Andric void CallBase::setDoesNotAccessMemory() { 628bdd1243dSDimitry Andric setMemoryEffects(MemoryEffects::none()); 629bdd1243dSDimitry Andric } 630bdd1243dSDimitry Andric 631bdd1243dSDimitry Andric /// Determine if the function does not access or only reads memory. 632bdd1243dSDimitry Andric bool CallBase::onlyReadsMemory() const { 633bdd1243dSDimitry Andric return getMemoryEffects().onlyReadsMemory(); 634bdd1243dSDimitry Andric } 635bdd1243dSDimitry Andric void CallBase::setOnlyReadsMemory() { 636bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly()); 637bdd1243dSDimitry Andric } 638bdd1243dSDimitry Andric 639bdd1243dSDimitry Andric /// Determine if the function does not access or only writes memory. 640bdd1243dSDimitry Andric bool CallBase::onlyWritesMemory() const { 641bdd1243dSDimitry Andric return getMemoryEffects().onlyWritesMemory(); 642bdd1243dSDimitry Andric } 643bdd1243dSDimitry Andric void CallBase::setOnlyWritesMemory() { 644bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly()); 645bdd1243dSDimitry Andric } 646bdd1243dSDimitry Andric 647bdd1243dSDimitry Andric /// Determine if the call can access memmory only using pointers based 648bdd1243dSDimitry Andric /// on its arguments. 649bdd1243dSDimitry Andric bool CallBase::onlyAccessesArgMemory() const { 650bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesArgPointees(); 651bdd1243dSDimitry Andric } 652bdd1243dSDimitry Andric void CallBase::setOnlyAccessesArgMemory() { 653bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly()); 654bdd1243dSDimitry Andric } 655bdd1243dSDimitry Andric 656bdd1243dSDimitry Andric /// Determine if the function may only access memory that is 657bdd1243dSDimitry Andric /// inaccessible from the IR. 658bdd1243dSDimitry Andric bool CallBase::onlyAccessesInaccessibleMemory() const { 659bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesInaccessibleMem(); 660bdd1243dSDimitry Andric } 661bdd1243dSDimitry Andric void CallBase::setOnlyAccessesInaccessibleMemory() { 662bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly()); 663bdd1243dSDimitry Andric } 664bdd1243dSDimitry Andric 665bdd1243dSDimitry Andric /// Determine if the function may only access memory that is 666bdd1243dSDimitry Andric /// either inaccessible from the IR or pointed to by its arguments. 667bdd1243dSDimitry Andric bool CallBase::onlyAccessesInaccessibleMemOrArgMem() const { 668bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesInaccessibleOrArgMem(); 669bdd1243dSDimitry Andric } 670bdd1243dSDimitry Andric void CallBase::setOnlyAccessesInaccessibleMemOrArgMem() { 671bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & 672bdd1243dSDimitry Andric MemoryEffects::inaccessibleOrArgMemOnly()); 673bdd1243dSDimitry Andric } 674bdd1243dSDimitry Andric 6750b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6760b57cec5SDimitry Andric // CallInst Implementation 6770b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args, 6800b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) { 6810b57cec5SDimitry Andric this->FTy = FTy; 6820b57cec5SDimitry Andric assert(getNumOperands() == Args.size() + CountBundleInputs(Bundles) + 1 && 6830b57cec5SDimitry Andric "NumOperands not set up?"); 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric #ifndef NDEBUG 6860b57cec5SDimitry Andric assert((Args.size() == FTy->getNumParams() || 6870b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && 6880b57cec5SDimitry Andric "Calling a function with bad signature!"); 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric for (unsigned i = 0; i != Args.size(); ++i) 6910b57cec5SDimitry Andric assert((i >= FTy->getNumParams() || 6920b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) && 6930b57cec5SDimitry Andric "Calling a function with a bad signature!"); 6940b57cec5SDimitry Andric #endif 6950b57cec5SDimitry Andric 696fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order 697fe6060f1SDimitry Andric // prediction. 6980b57cec5SDimitry Andric llvm::copy(Args, op_begin()); 699fe6060f1SDimitry Andric setCalledOperand(Func); 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size()); 7020b57cec5SDimitry Andric (void)It; 7030b57cec5SDimitry Andric assert(It + 1 == op_end() && "Should add up!"); 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric setName(NameStr); 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric void CallInst::init(FunctionType *FTy, Value *Func, const Twine &NameStr) { 7090b57cec5SDimitry Andric this->FTy = FTy; 7100b57cec5SDimitry Andric assert(getNumOperands() == 1 && "NumOperands not set up?"); 7110b57cec5SDimitry Andric setCalledOperand(Func); 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric setName(NameStr); 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name, 719*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 7200b57cec5SDimitry Andric : CallBase(Ty->getReturnType(), Instruction::Call, 7210b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - 1, 1, InsertBefore) { 7220b57cec5SDimitry Andric init(Ty, Func, Name); 7230b57cec5SDimitry Andric } 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric CallInst::CallInst(const CallInst &CI) 7260b57cec5SDimitry Andric : CallBase(CI.Attrs, CI.FTy, CI.getType(), Instruction::Call, 7270b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - CI.getNumOperands(), 7280b57cec5SDimitry Andric CI.getNumOperands()) { 7290b57cec5SDimitry Andric setTailCallKind(CI.getTailCallKind()); 7300b57cec5SDimitry Andric setCallingConv(CI.getCallingConv()); 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric std::copy(CI.op_begin(), CI.op_end(), op_begin()); 7330b57cec5SDimitry Andric std::copy(CI.bundle_op_info_begin(), CI.bundle_op_info_end(), 7340b57cec5SDimitry Andric bundle_op_info_begin()); 7350b57cec5SDimitry Andric SubclassOptionalData = CI.SubclassOptionalData; 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric CallInst *CallInst::Create(CallInst *CI, ArrayRef<OperandBundleDef> OpB, 739*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 7400b57cec5SDimitry Andric std::vector<Value *> Args(CI->arg_begin(), CI->arg_end()); 7410b57cec5SDimitry Andric 7425ffd83dbSDimitry Andric auto *NewCI = CallInst::Create(CI->getFunctionType(), CI->getCalledOperand(), 7430b57cec5SDimitry Andric Args, OpB, CI->getName(), InsertPt); 7440b57cec5SDimitry Andric NewCI->setTailCallKind(CI->getTailCallKind()); 7450b57cec5SDimitry Andric NewCI->setCallingConv(CI->getCallingConv()); 7460b57cec5SDimitry Andric NewCI->SubclassOptionalData = CI->SubclassOptionalData; 7470b57cec5SDimitry Andric NewCI->setAttributes(CI->getAttributes()); 7480b57cec5SDimitry Andric NewCI->setDebugLoc(CI->getDebugLoc()); 7490b57cec5SDimitry Andric return NewCI; 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric // Update profile weight for call instruction by scaling it using the ratio 7530b57cec5SDimitry Andric // of S/T. The meaning of "branch_weights" meta data for call instruction is 7540b57cec5SDimitry Andric // transfered to represent call count. 7550b57cec5SDimitry Andric void CallInst::updateProfWeight(uint64_t S, uint64_t T) { 7560b57cec5SDimitry Andric if (T == 0) { 7570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Attempting to update profile weights will result in " 7580b57cec5SDimitry Andric "div by 0. Ignoring. Likely the function " 7590b57cec5SDimitry Andric << getParent()->getParent()->getName() 7600b57cec5SDimitry Andric << " has 0 entry count, and contains call instructions " 7610b57cec5SDimitry Andric "with non-zero prof info."); 7620b57cec5SDimitry Andric return; 7630b57cec5SDimitry Andric } 764*0fca6ea1SDimitry Andric scaleProfData(*this, S, T); 7650b57cec5SDimitry Andric } 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 7680b57cec5SDimitry Andric // InvokeInst Implementation 7690b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal, 7720b57cec5SDimitry Andric BasicBlock *IfException, ArrayRef<Value *> Args, 7730b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles, 7740b57cec5SDimitry Andric const Twine &NameStr) { 7750b57cec5SDimitry Andric this->FTy = FTy; 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric assert((int)getNumOperands() == 7780b57cec5SDimitry Andric ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)) && 7790b57cec5SDimitry Andric "NumOperands not set up?"); 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric #ifndef NDEBUG 7820b57cec5SDimitry Andric assert(((Args.size() == FTy->getNumParams()) || 7830b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && 7840b57cec5SDimitry Andric "Invoking a function with bad signature"); 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric for (unsigned i = 0, e = Args.size(); i != e; i++) 7870b57cec5SDimitry Andric assert((i >= FTy->getNumParams() || 7880b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) && 7890b57cec5SDimitry Andric "Invoking a function with a bad signature!"); 7900b57cec5SDimitry Andric #endif 7910b57cec5SDimitry Andric 792fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order 793fe6060f1SDimitry Andric // prediction. 7940b57cec5SDimitry Andric llvm::copy(Args, op_begin()); 795fe6060f1SDimitry Andric setNormalDest(IfNormal); 796fe6060f1SDimitry Andric setUnwindDest(IfException); 797fe6060f1SDimitry Andric setCalledOperand(Fn); 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size()); 8000b57cec5SDimitry Andric (void)It; 8010b57cec5SDimitry Andric assert(It + 3 == op_end() && "Should add up!"); 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric setName(NameStr); 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric InvokeInst::InvokeInst(const InvokeInst &II) 8070b57cec5SDimitry Andric : CallBase(II.Attrs, II.FTy, II.getType(), Instruction::Invoke, 8080b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - II.getNumOperands(), 8090b57cec5SDimitry Andric II.getNumOperands()) { 8100b57cec5SDimitry Andric setCallingConv(II.getCallingConv()); 8110b57cec5SDimitry Andric std::copy(II.op_begin(), II.op_end(), op_begin()); 8120b57cec5SDimitry Andric std::copy(II.bundle_op_info_begin(), II.bundle_op_info_end(), 8130b57cec5SDimitry Andric bundle_op_info_begin()); 8140b57cec5SDimitry Andric SubclassOptionalData = II.SubclassOptionalData; 8150b57cec5SDimitry Andric } 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric InvokeInst *InvokeInst::Create(InvokeInst *II, ArrayRef<OperandBundleDef> OpB, 818*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 8190b57cec5SDimitry Andric std::vector<Value *> Args(II->arg_begin(), II->arg_end()); 8200b57cec5SDimitry Andric 8215ffd83dbSDimitry Andric auto *NewII = InvokeInst::Create( 8225ffd83dbSDimitry Andric II->getFunctionType(), II->getCalledOperand(), II->getNormalDest(), 8235ffd83dbSDimitry Andric II->getUnwindDest(), Args, OpB, II->getName(), InsertPt); 8240b57cec5SDimitry Andric NewII->setCallingConv(II->getCallingConv()); 8250b57cec5SDimitry Andric NewII->SubclassOptionalData = II->SubclassOptionalData; 8260b57cec5SDimitry Andric NewII->setAttributes(II->getAttributes()); 8270b57cec5SDimitry Andric NewII->setDebugLoc(II->getDebugLoc()); 8280b57cec5SDimitry Andric return NewII; 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric LandingPadInst *InvokeInst::getLandingPadInst() const { 8320b57cec5SDimitry Andric return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI()); 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric 835*0fca6ea1SDimitry Andric void InvokeInst::updateProfWeight(uint64_t S, uint64_t T) { 836*0fca6ea1SDimitry Andric if (T == 0) { 837*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "Attempting to update profile weights will result in " 838*0fca6ea1SDimitry Andric "div by 0. Ignoring. Likely the function " 839*0fca6ea1SDimitry Andric << getParent()->getParent()->getName() 840*0fca6ea1SDimitry Andric << " has 0 entry count, and contains call instructions " 841*0fca6ea1SDimitry Andric "with non-zero prof info."); 842*0fca6ea1SDimitry Andric return; 843*0fca6ea1SDimitry Andric } 844*0fca6ea1SDimitry Andric scaleProfData(*this, S, T); 845*0fca6ea1SDimitry Andric } 846*0fca6ea1SDimitry Andric 8470b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8480b57cec5SDimitry Andric // CallBrInst Implementation 8490b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric void CallBrInst::init(FunctionType *FTy, Value *Fn, BasicBlock *Fallthrough, 8520b57cec5SDimitry Andric ArrayRef<BasicBlock *> IndirectDests, 8530b57cec5SDimitry Andric ArrayRef<Value *> Args, 8540b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles, 8550b57cec5SDimitry Andric const Twine &NameStr) { 8560b57cec5SDimitry Andric this->FTy = FTy; 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric assert((int)getNumOperands() == 8590b57cec5SDimitry Andric ComputeNumOperands(Args.size(), IndirectDests.size(), 8600b57cec5SDimitry Andric CountBundleInputs(Bundles)) && 8610b57cec5SDimitry Andric "NumOperands not set up?"); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric #ifndef NDEBUG 8640b57cec5SDimitry Andric assert(((Args.size() == FTy->getNumParams()) || 8650b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && 8660b57cec5SDimitry Andric "Calling a function with bad signature"); 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric for (unsigned i = 0, e = Args.size(); i != e; i++) 8690b57cec5SDimitry Andric assert((i >= FTy->getNumParams() || 8700b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) && 8710b57cec5SDimitry Andric "Calling a function with a bad signature!"); 8720b57cec5SDimitry Andric #endif 8730b57cec5SDimitry Andric 874fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order 875fe6060f1SDimitry Andric // prediction. 8760b57cec5SDimitry Andric std::copy(Args.begin(), Args.end(), op_begin()); 877fe6060f1SDimitry Andric NumIndirectDests = IndirectDests.size(); 878fe6060f1SDimitry Andric setDefaultDest(Fallthrough); 879fe6060f1SDimitry Andric for (unsigned i = 0; i != NumIndirectDests; ++i) 880fe6060f1SDimitry Andric setIndirectDest(i, IndirectDests[i]); 881fe6060f1SDimitry Andric setCalledOperand(Fn); 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size()); 8840b57cec5SDimitry Andric (void)It; 8850b57cec5SDimitry Andric assert(It + 2 + IndirectDests.size() == op_end() && "Should add up!"); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric setName(NameStr); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric CallBrInst::CallBrInst(const CallBrInst &CBI) 8910b57cec5SDimitry Andric : CallBase(CBI.Attrs, CBI.FTy, CBI.getType(), Instruction::CallBr, 8920b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - CBI.getNumOperands(), 8930b57cec5SDimitry Andric CBI.getNumOperands()) { 8940b57cec5SDimitry Andric setCallingConv(CBI.getCallingConv()); 8950b57cec5SDimitry Andric std::copy(CBI.op_begin(), CBI.op_end(), op_begin()); 8960b57cec5SDimitry Andric std::copy(CBI.bundle_op_info_begin(), CBI.bundle_op_info_end(), 8970b57cec5SDimitry Andric bundle_op_info_begin()); 8980b57cec5SDimitry Andric SubclassOptionalData = CBI.SubclassOptionalData; 8990b57cec5SDimitry Andric NumIndirectDests = CBI.NumIndirectDests; 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric CallBrInst *CallBrInst::Create(CallBrInst *CBI, ArrayRef<OperandBundleDef> OpB, 903*0fca6ea1SDimitry Andric InsertPosition InsertPt) { 9040b57cec5SDimitry Andric std::vector<Value *> Args(CBI->arg_begin(), CBI->arg_end()); 9050b57cec5SDimitry Andric 9065ffd83dbSDimitry Andric auto *NewCBI = CallBrInst::Create( 9075ffd83dbSDimitry Andric CBI->getFunctionType(), CBI->getCalledOperand(), CBI->getDefaultDest(), 9085ffd83dbSDimitry Andric CBI->getIndirectDests(), Args, OpB, CBI->getName(), InsertPt); 9090b57cec5SDimitry Andric NewCBI->setCallingConv(CBI->getCallingConv()); 9100b57cec5SDimitry Andric NewCBI->SubclassOptionalData = CBI->SubclassOptionalData; 9110b57cec5SDimitry Andric NewCBI->setAttributes(CBI->getAttributes()); 9120b57cec5SDimitry Andric NewCBI->setDebugLoc(CBI->getDebugLoc()); 9130b57cec5SDimitry Andric NewCBI->NumIndirectDests = CBI->NumIndirectDests; 9140b57cec5SDimitry Andric return NewCBI; 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9180b57cec5SDimitry Andric // ReturnInst Implementation 9190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric ReturnInst::ReturnInst(const ReturnInst &RI) 9220b57cec5SDimitry Andric : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Ret, 9230b57cec5SDimitry Andric OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(), 9240b57cec5SDimitry Andric RI.getNumOperands()) { 9250b57cec5SDimitry Andric if (RI.getNumOperands()) 9260b57cec5SDimitry Andric Op<0>() = RI.Op<0>(); 9270b57cec5SDimitry Andric SubclassOptionalData = RI.SubclassOptionalData; 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric 930*0fca6ea1SDimitry Andric ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, 931*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 9320b57cec5SDimitry Andric : Instruction(Type::getVoidTy(C), Instruction::Ret, 9330b57cec5SDimitry Andric OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal, 9340b57cec5SDimitry Andric InsertBefore) { 9350b57cec5SDimitry Andric if (retVal) 9360b57cec5SDimitry Andric Op<0>() = retVal; 9370b57cec5SDimitry Andric } 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9400b57cec5SDimitry Andric // ResumeInst Implementation 9410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric ResumeInst::ResumeInst(const ResumeInst &RI) 9440b57cec5SDimitry Andric : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Resume, 9450b57cec5SDimitry Andric OperandTraits<ResumeInst>::op_begin(this), 1) { 9460b57cec5SDimitry Andric Op<0>() = RI.Op<0>(); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 949*0fca6ea1SDimitry Andric ResumeInst::ResumeInst(Value *Exn, InsertPosition InsertBefore) 9500b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Exn->getContext()), Instruction::Resume, 9510b57cec5SDimitry Andric OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) { 9520b57cec5SDimitry Andric Op<0>() = Exn; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9560b57cec5SDimitry Andric // CleanupReturnInst Implementation 9570b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI) 9600b57cec5SDimitry Andric : Instruction(CRI.getType(), Instruction::CleanupRet, 9610b57cec5SDimitry Andric OperandTraits<CleanupReturnInst>::op_end(this) - 9620b57cec5SDimitry Andric CRI.getNumOperands(), 9630b57cec5SDimitry Andric CRI.getNumOperands()) { 9645ffd83dbSDimitry Andric setSubclassData<Instruction::OpaqueField>( 9655ffd83dbSDimitry Andric CRI.getSubclassData<Instruction::OpaqueField>()); 9660b57cec5SDimitry Andric Op<0>() = CRI.Op<0>(); 9670b57cec5SDimitry Andric if (CRI.hasUnwindDest()) 9680b57cec5SDimitry Andric Op<1>() = CRI.Op<1>(); 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) { 9720b57cec5SDimitry Andric if (UnwindBB) 9735ffd83dbSDimitry Andric setSubclassData<UnwindDestField>(true); 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric Op<0>() = CleanupPad; 9760b57cec5SDimitry Andric if (UnwindBB) 9770b57cec5SDimitry Andric Op<1>() = UnwindBB; 9780b57cec5SDimitry Andric } 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, 981*0fca6ea1SDimitry Andric unsigned Values, 982*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 9830b57cec5SDimitry Andric : Instruction(Type::getVoidTy(CleanupPad->getContext()), 9840b57cec5SDimitry Andric Instruction::CleanupRet, 9850b57cec5SDimitry Andric OperandTraits<CleanupReturnInst>::op_end(this) - Values, 9860b57cec5SDimitry Andric Values, InsertBefore) { 9870b57cec5SDimitry Andric init(CleanupPad, UnwindBB); 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9910b57cec5SDimitry Andric // CatchReturnInst Implementation 9920b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9930b57cec5SDimitry Andric void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) { 9940b57cec5SDimitry Andric Op<0>() = CatchPad; 9950b57cec5SDimitry Andric Op<1>() = BB; 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI) 9990b57cec5SDimitry Andric : Instruction(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet, 10000b57cec5SDimitry Andric OperandTraits<CatchReturnInst>::op_begin(this), 2) { 10010b57cec5SDimitry Andric Op<0>() = CRI.Op<0>(); 10020b57cec5SDimitry Andric Op<1>() = CRI.Op<1>(); 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB, 1006*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 10070b57cec5SDimitry Andric : Instruction(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, 10080b57cec5SDimitry Andric OperandTraits<CatchReturnInst>::op_begin(this), 2, 10090b57cec5SDimitry Andric InsertBefore) { 10100b57cec5SDimitry Andric init(CatchPad, BB); 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10140b57cec5SDimitry Andric // CatchSwitchInst Implementation 10150b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, 10180b57cec5SDimitry Andric unsigned NumReservedValues, 10190b57cec5SDimitry Andric const Twine &NameStr, 1020*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 10210b57cec5SDimitry Andric : Instruction(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0, 10220b57cec5SDimitry Andric InsertBefore) { 10230b57cec5SDimitry Andric if (UnwindDest) 10240b57cec5SDimitry Andric ++NumReservedValues; 10250b57cec5SDimitry Andric init(ParentPad, UnwindDest, NumReservedValues + 1); 10260b57cec5SDimitry Andric setName(NameStr); 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI) 10300b57cec5SDimitry Andric : Instruction(CSI.getType(), Instruction::CatchSwitch, nullptr, 10310b57cec5SDimitry Andric CSI.getNumOperands()) { 10320b57cec5SDimitry Andric init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands()); 10330b57cec5SDimitry Andric setNumHungOffUseOperands(ReservedSpace); 10340b57cec5SDimitry Andric Use *OL = getOperandList(); 10350b57cec5SDimitry Andric const Use *InOL = CSI.getOperandList(); 10360b57cec5SDimitry Andric for (unsigned I = 1, E = ReservedSpace; I != E; ++I) 10370b57cec5SDimitry Andric OL[I] = InOL[I]; 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest, 10410b57cec5SDimitry Andric unsigned NumReservedValues) { 10420b57cec5SDimitry Andric assert(ParentPad && NumReservedValues); 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric ReservedSpace = NumReservedValues; 10450b57cec5SDimitry Andric setNumHungOffUseOperands(UnwindDest ? 2 : 1); 10460b57cec5SDimitry Andric allocHungoffUses(ReservedSpace); 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric Op<0>() = ParentPad; 10490b57cec5SDimitry Andric if (UnwindDest) { 10505ffd83dbSDimitry Andric setSubclassData<UnwindDestField>(true); 10510b57cec5SDimitry Andric setUnwindDest(UnwindDest); 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric } 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response to a 10560b57cec5SDimitry Andric /// push_back style of operation. This grows the number of ops by 2 times. 10570b57cec5SDimitry Andric void CatchSwitchInst::growOperands(unsigned Size) { 10580b57cec5SDimitry Andric unsigned NumOperands = getNumOperands(); 10590b57cec5SDimitry Andric assert(NumOperands >= 1); 10600b57cec5SDimitry Andric if (ReservedSpace >= NumOperands + Size) 10610b57cec5SDimitry Andric return; 10620b57cec5SDimitry Andric ReservedSpace = (NumOperands + Size / 2) * 2; 10630b57cec5SDimitry Andric growHungoffUses(ReservedSpace); 10640b57cec5SDimitry Andric } 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andric void CatchSwitchInst::addHandler(BasicBlock *Handler) { 10670b57cec5SDimitry Andric unsigned OpNo = getNumOperands(); 10680b57cec5SDimitry Andric growOperands(1); 10690b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!"); 10700b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() + 1); 10710b57cec5SDimitry Andric getOperandList()[OpNo] = Handler; 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric void CatchSwitchInst::removeHandler(handler_iterator HI) { 10750b57cec5SDimitry Andric // Move all subsequent handlers up one. 10760b57cec5SDimitry Andric Use *EndDst = op_end() - 1; 10770b57cec5SDimitry Andric for (Use *CurDst = HI.getCurrent(); CurDst != EndDst; ++CurDst) 10780b57cec5SDimitry Andric *CurDst = *(CurDst + 1); 10790b57cec5SDimitry Andric // Null out the last handler use. 10800b57cec5SDimitry Andric *EndDst = nullptr; 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() - 1); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10860b57cec5SDimitry Andric // FuncletPadInst Implementation 10870b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10880b57cec5SDimitry Andric void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args, 10890b57cec5SDimitry Andric const Twine &NameStr) { 10900b57cec5SDimitry Andric assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?"); 10910b57cec5SDimitry Andric llvm::copy(Args, op_begin()); 10920b57cec5SDimitry Andric setParentPad(ParentPad); 10930b57cec5SDimitry Andric setName(NameStr); 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI) 10970b57cec5SDimitry Andric : Instruction(FPI.getType(), FPI.getOpcode(), 10980b57cec5SDimitry Andric OperandTraits<FuncletPadInst>::op_end(this) - 10990b57cec5SDimitry Andric FPI.getNumOperands(), 11000b57cec5SDimitry Andric FPI.getNumOperands()) { 11010b57cec5SDimitry Andric std::copy(FPI.op_begin(), FPI.op_end(), op_begin()); 11020b57cec5SDimitry Andric setParentPad(FPI.getParentPad()); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, 11060b57cec5SDimitry Andric ArrayRef<Value *> Args, unsigned Values, 1107*0fca6ea1SDimitry Andric const Twine &NameStr, 1108*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 11090b57cec5SDimitry Andric : Instruction(ParentPad->getType(), Op, 11100b57cec5SDimitry Andric OperandTraits<FuncletPadInst>::op_end(this) - Values, Values, 11110b57cec5SDimitry Andric InsertBefore) { 11120b57cec5SDimitry Andric init(ParentPad, Args, NameStr); 11130b57cec5SDimitry Andric } 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11160b57cec5SDimitry Andric // UnreachableInst Implementation 11170b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric UnreachableInst::UnreachableInst(LLVMContext &Context, 1120*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 11210b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr, 11220b57cec5SDimitry Andric 0, InsertBefore) {} 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11250b57cec5SDimitry Andric // BranchInst Implementation 11260b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric void BranchInst::AssertOK() { 11290b57cec5SDimitry Andric if (isConditional()) 11300b57cec5SDimitry Andric assert(getCondition()->getType()->isIntegerTy(1) && 11310b57cec5SDimitry Andric "May only branch on boolean predicates!"); 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric 1134*0fca6ea1SDimitry Andric BranchInst::BranchInst(BasicBlock *IfTrue, InsertPosition InsertBefore) 11350b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, 11360b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - 1, 1, 11370b57cec5SDimitry Andric InsertBefore) { 11380b57cec5SDimitry Andric assert(IfTrue && "Branch destination may not be null!"); 11390b57cec5SDimitry Andric Op<-1>() = IfTrue; 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, 1143*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 11440b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, 11450b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - 3, 3, 11460b57cec5SDimitry Andric InsertBefore) { 1147fe6060f1SDimitry Andric // Assign in order of operand index to make use-list order predictable. 11480b57cec5SDimitry Andric Op<-3>() = Cond; 1149fe6060f1SDimitry Andric Op<-2>() = IfFalse; 1150fe6060f1SDimitry Andric Op<-1>() = IfTrue; 11510b57cec5SDimitry Andric #ifndef NDEBUG 11520b57cec5SDimitry Andric AssertOK(); 11530b57cec5SDimitry Andric #endif 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric BranchInst::BranchInst(const BranchInst &BI) 11570b57cec5SDimitry Andric : Instruction(Type::getVoidTy(BI.getContext()), Instruction::Br, 11580b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(), 11590b57cec5SDimitry Andric BI.getNumOperands()) { 1160fe6060f1SDimitry Andric // Assign in order of operand index to make use-list order predictable. 11610b57cec5SDimitry Andric if (BI.getNumOperands() != 1) { 11620b57cec5SDimitry Andric assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!"); 11630b57cec5SDimitry Andric Op<-3>() = BI.Op<-3>(); 11640b57cec5SDimitry Andric Op<-2>() = BI.Op<-2>(); 11650b57cec5SDimitry Andric } 1166fe6060f1SDimitry Andric Op<-1>() = BI.Op<-1>(); 11670b57cec5SDimitry Andric SubclassOptionalData = BI.SubclassOptionalData; 11680b57cec5SDimitry Andric } 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric void BranchInst::swapSuccessors() { 11710b57cec5SDimitry Andric assert(isConditional() && 11720b57cec5SDimitry Andric "Cannot swap successors of an unconditional branch"); 11730b57cec5SDimitry Andric Op<-1>().swap(Op<-2>()); 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric // Update profile metadata if present and it matches our structural 11760b57cec5SDimitry Andric // expectations. 11770b57cec5SDimitry Andric swapProfMetadata(); 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11810b57cec5SDimitry Andric // AllocaInst Implementation 11820b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric static Value *getAISize(LLVMContext &Context, Value *Amt) { 11850b57cec5SDimitry Andric if (!Amt) 11860b57cec5SDimitry Andric Amt = ConstantInt::get(Type::getInt32Ty(Context), 1); 11870b57cec5SDimitry Andric else { 11880b57cec5SDimitry Andric assert(!isa<BasicBlock>(Amt) && 11890b57cec5SDimitry Andric "Passed basic block into allocation size parameter! Use other ctor"); 11900b57cec5SDimitry Andric assert(Amt->getType()->isIntegerTy() && 11910b57cec5SDimitry Andric "Allocation array size is not an integer!"); 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric return Amt; 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 1196*0fca6ea1SDimitry Andric static Align computeAllocaDefaultAlign(Type *Ty, InsertPosition Pos) { 1197*0fca6ea1SDimitry Andric assert(Pos.isValid() && 1198*0fca6ea1SDimitry Andric "Insertion position cannot be null when alignment not provided!"); 1199*0fca6ea1SDimitry Andric BasicBlock *BB = Pos.getBasicBlock(); 12005ffd83dbSDimitry Andric assert(BB->getParent() && 12015ffd83dbSDimitry Andric "BB must be in a Function when alignment not provided!"); 1202*0fca6ea1SDimitry Andric const DataLayout &DL = BB->getDataLayout(); 12035ffd83dbSDimitry Andric return DL.getPrefTypeAlign(Ty); 12045ffd83dbSDimitry Andric } 12055ffd83dbSDimitry Andric 12060b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, 1207*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 12080b57cec5SDimitry Andric : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertBefore) {} 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, 1211*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) 12125ffd83dbSDimitry Andric : AllocaInst(Ty, AddrSpace, ArraySize, 12135ffd83dbSDimitry Andric computeAllocaDefaultAlign(Ty, InsertBefore), Name, 12145ffd83dbSDimitry Andric InsertBefore) {} 12150b57cec5SDimitry Andric 12160b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, 12175ffd83dbSDimitry Andric Align Align, const Twine &Name, 1218*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 12190b57cec5SDimitry Andric : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, 12200b57cec5SDimitry Andric getAISize(Ty->getContext(), ArraySize), InsertBefore), 12210b57cec5SDimitry Andric AllocatedType(Ty) { 12225ffd83dbSDimitry Andric setAlignment(Align); 12230b57cec5SDimitry Andric assert(!Ty->isVoidTy() && "Cannot allocate void!"); 12240b57cec5SDimitry Andric setName(Name); 12250b57cec5SDimitry Andric } 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric bool AllocaInst::isArrayAllocation() const { 12280b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0))) 12290b57cec5SDimitry Andric return !CI->isOne(); 12300b57cec5SDimitry Andric return true; 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric 12330b57cec5SDimitry Andric /// isStaticAlloca - Return true if this alloca is in the entry block of the 12340b57cec5SDimitry Andric /// function and is a constant size. If so, the code generator will fold it 12350b57cec5SDimitry Andric /// into the prolog/epilog code, so it is basically free. 12360b57cec5SDimitry Andric bool AllocaInst::isStaticAlloca() const { 12370b57cec5SDimitry Andric // Must be constant size. 12380b57cec5SDimitry Andric if (!isa<ConstantInt>(getArraySize())) return false; 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric // Must be in the entry block. 12410b57cec5SDimitry Andric const BasicBlock *Parent = getParent(); 1242bdd1243dSDimitry Andric return Parent->isEntryBlock() && !isUsedWithInAlloca(); 12430b57cec5SDimitry Andric } 12440b57cec5SDimitry Andric 12450b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12460b57cec5SDimitry Andric // LoadInst Implementation 12470b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric void LoadInst::AssertOK() { 12500b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() && 12510b57cec5SDimitry Andric "Ptr must have pointer type."); 12520b57cec5SDimitry Andric } 12530b57cec5SDimitry Andric 1254*0fca6ea1SDimitry Andric static Align computeLoadStoreDefaultAlign(Type *Ty, InsertPosition Pos) { 1255*0fca6ea1SDimitry Andric assert(Pos.isValid() && 1256*0fca6ea1SDimitry Andric "Insertion position cannot be null when alignment not provided!"); 1257*0fca6ea1SDimitry Andric BasicBlock *BB = Pos.getBasicBlock(); 12585ffd83dbSDimitry Andric assert(BB->getParent() && 12595ffd83dbSDimitry Andric "BB must be in a Function when alignment not provided!"); 1260*0fca6ea1SDimitry Andric const DataLayout &DL = BB->getDataLayout(); 12615ffd83dbSDimitry Andric return DL.getABITypeAlign(Ty); 12625ffd83dbSDimitry Andric } 12635ffd83dbSDimitry Andric 12640b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, 1265*0fca6ea1SDimitry Andric InsertPosition InsertBef) 12660b57cec5SDimitry Andric : LoadInst(Ty, Ptr, Name, /*isVolatile=*/false, InsertBef) {} 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, 1269*0fca6ea1SDimitry Andric InsertPosition InsertBef) 12705ffd83dbSDimitry Andric : LoadInst(Ty, Ptr, Name, isVolatile, 12715ffd83dbSDimitry Andric computeLoadStoreDefaultAlign(Ty, InsertBef), InsertBef) {} 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, 1274*0fca6ea1SDimitry Andric Align Align, InsertPosition InsertBef) 12750b57cec5SDimitry Andric : LoadInst(Ty, Ptr, Name, isVolatile, Align, AtomicOrdering::NotAtomic, 12760b57cec5SDimitry Andric SyncScope::System, InsertBef) {} 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, 12795ffd83dbSDimitry Andric Align Align, AtomicOrdering Order, SyncScope::ID SSID, 1280*0fca6ea1SDimitry Andric InsertPosition InsertBef) 12810b57cec5SDimitry Andric : UnaryInstruction(Ty, Load, Ptr, InsertBef) { 12820b57cec5SDimitry Andric setVolatile(isVolatile); 12830b57cec5SDimitry Andric setAlignment(Align); 12840b57cec5SDimitry Andric setAtomic(Order, SSID); 12850b57cec5SDimitry Andric AssertOK(); 12860b57cec5SDimitry Andric setName(Name); 12870b57cec5SDimitry Andric } 12880b57cec5SDimitry Andric 12890b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12900b57cec5SDimitry Andric // StoreInst Implementation 12910b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric void StoreInst::AssertOK() { 12940b57cec5SDimitry Andric assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!"); 12950b57cec5SDimitry Andric assert(getOperand(1)->getType()->isPointerTy() && 12960b57cec5SDimitry Andric "Ptr must have pointer type!"); 12970b57cec5SDimitry Andric } 12980b57cec5SDimitry Andric 1299*0fca6ea1SDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, InsertPosition InsertBefore) 13005f757f3fSDimitry Andric : StoreInst(val, addr, /*isVolatile=*/false, InsertBefore) {} 13015f757f3fSDimitry Andric 13020b57cec5SDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, 1303*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 13045ffd83dbSDimitry Andric : StoreInst(val, addr, isVolatile, 13055ffd83dbSDimitry Andric computeLoadStoreDefaultAlign(val->getType(), InsertBefore), 13065ffd83dbSDimitry Andric InsertBefore) {} 13070b57cec5SDimitry Andric 13085ffd83dbSDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align, 1309*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 13105f757f3fSDimitry Andric : StoreInst(val, addr, isVolatile, Align, AtomicOrdering::NotAtomic, 13115f757f3fSDimitry Andric SyncScope::System, InsertBefore) {} 13125f757f3fSDimitry Andric 13135f757f3fSDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align, 13148bcb0991SDimitry Andric AtomicOrdering Order, SyncScope::ID SSID, 1315*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 13160b57cec5SDimitry Andric : Instruction(Type::getVoidTy(val->getContext()), Store, 13170b57cec5SDimitry Andric OperandTraits<StoreInst>::op_begin(this), 13188bcb0991SDimitry Andric OperandTraits<StoreInst>::operands(this), InsertBefore) { 13190b57cec5SDimitry Andric Op<0>() = val; 13200b57cec5SDimitry Andric Op<1>() = addr; 13210b57cec5SDimitry Andric setVolatile(isVolatile); 13220b57cec5SDimitry Andric setAlignment(Align); 13230b57cec5SDimitry Andric setAtomic(Order, SSID); 13240b57cec5SDimitry Andric AssertOK(); 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13280b57cec5SDimitry Andric // AtomicCmpXchgInst Implementation 13290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal, 13325ffd83dbSDimitry Andric Align Alignment, AtomicOrdering SuccessOrdering, 13330b57cec5SDimitry Andric AtomicOrdering FailureOrdering, 13340b57cec5SDimitry Andric SyncScope::ID SSID) { 13350b57cec5SDimitry Andric Op<0>() = Ptr; 13360b57cec5SDimitry Andric Op<1>() = Cmp; 13370b57cec5SDimitry Andric Op<2>() = NewVal; 13380b57cec5SDimitry Andric setSuccessOrdering(SuccessOrdering); 13390b57cec5SDimitry Andric setFailureOrdering(FailureOrdering); 13400b57cec5SDimitry Andric setSyncScopeID(SSID); 13415ffd83dbSDimitry Andric setAlignment(Alignment); 13420b57cec5SDimitry Andric 13430b57cec5SDimitry Andric assert(getOperand(0) && getOperand(1) && getOperand(2) && 13440b57cec5SDimitry Andric "All operands must be non-null!"); 13450b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() && 13460b57cec5SDimitry Andric "Ptr must have pointer type!"); 1347fe6060f1SDimitry Andric assert(getOperand(1)->getType() == getOperand(2)->getType() && 1348fe6060f1SDimitry Andric "Cmp type and NewVal type must be same!"); 13490b57cec5SDimitry Andric } 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, 13525ffd83dbSDimitry Andric Align Alignment, 13530b57cec5SDimitry Andric AtomicOrdering SuccessOrdering, 13540b57cec5SDimitry Andric AtomicOrdering FailureOrdering, 13550b57cec5SDimitry Andric SyncScope::ID SSID, 1356*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 13570b57cec5SDimitry Andric : Instruction( 13580b57cec5SDimitry Andric StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext())), 13590b57cec5SDimitry Andric AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this), 13600b57cec5SDimitry Andric OperandTraits<AtomicCmpXchgInst>::operands(this), InsertBefore) { 13615ffd83dbSDimitry Andric Init(Ptr, Cmp, NewVal, Alignment, SuccessOrdering, FailureOrdering, SSID); 13620b57cec5SDimitry Andric } 13630b57cec5SDimitry Andric 13640b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13650b57cec5SDimitry Andric // AtomicRMWInst Implementation 13660b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric void AtomicRMWInst::Init(BinOp Operation, Value *Ptr, Value *Val, 13695ffd83dbSDimitry Andric Align Alignment, AtomicOrdering Ordering, 13700b57cec5SDimitry Andric SyncScope::ID SSID) { 1371972a253aSDimitry Andric assert(Ordering != AtomicOrdering::NotAtomic && 1372972a253aSDimitry Andric "atomicrmw instructions can only be atomic."); 1373972a253aSDimitry Andric assert(Ordering != AtomicOrdering::Unordered && 1374972a253aSDimitry Andric "atomicrmw instructions cannot be unordered."); 13750b57cec5SDimitry Andric Op<0>() = Ptr; 13760b57cec5SDimitry Andric Op<1>() = Val; 13770b57cec5SDimitry Andric setOperation(Operation); 13780b57cec5SDimitry Andric setOrdering(Ordering); 13790b57cec5SDimitry Andric setSyncScopeID(SSID); 13805ffd83dbSDimitry Andric setAlignment(Alignment); 13810b57cec5SDimitry Andric 1382*0fca6ea1SDimitry Andric assert(getOperand(0) && getOperand(1) && "All operands must be non-null!"); 13830b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() && 13840b57cec5SDimitry Andric "Ptr must have pointer type!"); 13850b57cec5SDimitry Andric assert(Ordering != AtomicOrdering::NotAtomic && 13860b57cec5SDimitry Andric "AtomicRMW instructions must be atomic!"); 13870b57cec5SDimitry Andric } 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, 13905ffd83dbSDimitry Andric Align Alignment, AtomicOrdering Ordering, 1391*0fca6ea1SDimitry Andric SyncScope::ID SSID, InsertPosition InsertBefore) 13920b57cec5SDimitry Andric : Instruction(Val->getType(), AtomicRMW, 13930b57cec5SDimitry Andric OperandTraits<AtomicRMWInst>::op_begin(this), 13945ffd83dbSDimitry Andric OperandTraits<AtomicRMWInst>::operands(this), InsertBefore) { 13955ffd83dbSDimitry Andric Init(Operation, Ptr, Val, Alignment, Ordering, SSID); 13960b57cec5SDimitry Andric } 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric StringRef AtomicRMWInst::getOperationName(BinOp Op) { 13990b57cec5SDimitry Andric switch (Op) { 14000b57cec5SDimitry Andric case AtomicRMWInst::Xchg: 14010b57cec5SDimitry Andric return "xchg"; 14020b57cec5SDimitry Andric case AtomicRMWInst::Add: 14030b57cec5SDimitry Andric return "add"; 14040b57cec5SDimitry Andric case AtomicRMWInst::Sub: 14050b57cec5SDimitry Andric return "sub"; 14060b57cec5SDimitry Andric case AtomicRMWInst::And: 14070b57cec5SDimitry Andric return "and"; 14080b57cec5SDimitry Andric case AtomicRMWInst::Nand: 14090b57cec5SDimitry Andric return "nand"; 14100b57cec5SDimitry Andric case AtomicRMWInst::Or: 14110b57cec5SDimitry Andric return "or"; 14120b57cec5SDimitry Andric case AtomicRMWInst::Xor: 14130b57cec5SDimitry Andric return "xor"; 14140b57cec5SDimitry Andric case AtomicRMWInst::Max: 14150b57cec5SDimitry Andric return "max"; 14160b57cec5SDimitry Andric case AtomicRMWInst::Min: 14170b57cec5SDimitry Andric return "min"; 14180b57cec5SDimitry Andric case AtomicRMWInst::UMax: 14190b57cec5SDimitry Andric return "umax"; 14200b57cec5SDimitry Andric case AtomicRMWInst::UMin: 14210b57cec5SDimitry Andric return "umin"; 14220b57cec5SDimitry Andric case AtomicRMWInst::FAdd: 14230b57cec5SDimitry Andric return "fadd"; 14240b57cec5SDimitry Andric case AtomicRMWInst::FSub: 14250b57cec5SDimitry Andric return "fsub"; 1426753f127fSDimitry Andric case AtomicRMWInst::FMax: 1427753f127fSDimitry Andric return "fmax"; 1428753f127fSDimitry Andric case AtomicRMWInst::FMin: 1429753f127fSDimitry Andric return "fmin"; 1430bdd1243dSDimitry Andric case AtomicRMWInst::UIncWrap: 1431bdd1243dSDimitry Andric return "uinc_wrap"; 1432bdd1243dSDimitry Andric case AtomicRMWInst::UDecWrap: 1433bdd1243dSDimitry Andric return "udec_wrap"; 14340b57cec5SDimitry Andric case AtomicRMWInst::BAD_BINOP: 14350b57cec5SDimitry Andric return "<invalid operation>"; 14360b57cec5SDimitry Andric } 14370b57cec5SDimitry Andric 14380b57cec5SDimitry Andric llvm_unreachable("invalid atomicrmw operation"); 14390b57cec5SDimitry Andric } 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14420b57cec5SDimitry Andric // FenceInst Implementation 14430b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, 1446*0fca6ea1SDimitry Andric SyncScope::ID SSID, InsertPosition InsertBefore) 14470b57cec5SDimitry Andric : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) { 14480b57cec5SDimitry Andric setOrdering(Ordering); 14490b57cec5SDimitry Andric setSyncScopeID(SSID); 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14530b57cec5SDimitry Andric // GetElementPtrInst Implementation 14540b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric void GetElementPtrInst::init(Value *Ptr, ArrayRef<Value *> IdxList, 14570b57cec5SDimitry Andric const Twine &Name) { 14580b57cec5SDimitry Andric assert(getNumOperands() == 1 + IdxList.size() && 14590b57cec5SDimitry Andric "NumOperands not initialized?"); 14600b57cec5SDimitry Andric Op<0>() = Ptr; 14610b57cec5SDimitry Andric llvm::copy(IdxList, op_begin() + 1); 14620b57cec5SDimitry Andric setName(Name); 14630b57cec5SDimitry Andric } 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) 14660b57cec5SDimitry Andric : Instruction(GEPI.getType(), GetElementPtr, 14670b57cec5SDimitry Andric OperandTraits<GetElementPtrInst>::op_end(this) - 14680b57cec5SDimitry Andric GEPI.getNumOperands(), 14690b57cec5SDimitry Andric GEPI.getNumOperands()), 14700b57cec5SDimitry Andric SourceElementType(GEPI.SourceElementType), 14710b57cec5SDimitry Andric ResultElementType(GEPI.ResultElementType) { 14720b57cec5SDimitry Andric std::copy(GEPI.op_begin(), GEPI.op_end(), op_begin()); 14730b57cec5SDimitry Andric SubclassOptionalData = GEPI.SubclassOptionalData; 14740b57cec5SDimitry Andric } 14750b57cec5SDimitry Andric 14765ffd83dbSDimitry Andric Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, Value *Idx) { 14775ffd83dbSDimitry Andric if (auto *Struct = dyn_cast<StructType>(Ty)) { 14785ffd83dbSDimitry Andric if (!Struct->indexValid(Idx)) 14790b57cec5SDimitry Andric return nullptr; 14805ffd83dbSDimitry Andric return Struct->getTypeAtIndex(Idx); 14810b57cec5SDimitry Andric } 14825ffd83dbSDimitry Andric if (!Idx->getType()->isIntOrIntVectorTy()) 14835ffd83dbSDimitry Andric return nullptr; 14845ffd83dbSDimitry Andric if (auto *Array = dyn_cast<ArrayType>(Ty)) 14855ffd83dbSDimitry Andric return Array->getElementType(); 14865ffd83dbSDimitry Andric if (auto *Vector = dyn_cast<VectorType>(Ty)) 14875ffd83dbSDimitry Andric return Vector->getElementType(); 14885ffd83dbSDimitry Andric return nullptr; 14895ffd83dbSDimitry Andric } 14905ffd83dbSDimitry Andric 14915ffd83dbSDimitry Andric Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, uint64_t Idx) { 14925ffd83dbSDimitry Andric if (auto *Struct = dyn_cast<StructType>(Ty)) { 14935ffd83dbSDimitry Andric if (Idx >= Struct->getNumElements()) 14945ffd83dbSDimitry Andric return nullptr; 14955ffd83dbSDimitry Andric return Struct->getElementType(Idx); 14965ffd83dbSDimitry Andric } 14975ffd83dbSDimitry Andric if (auto *Array = dyn_cast<ArrayType>(Ty)) 14985ffd83dbSDimitry Andric return Array->getElementType(); 14995ffd83dbSDimitry Andric if (auto *Vector = dyn_cast<VectorType>(Ty)) 15005ffd83dbSDimitry Andric return Vector->getElementType(); 15015ffd83dbSDimitry Andric return nullptr; 15025ffd83dbSDimitry Andric } 15035ffd83dbSDimitry Andric 15045ffd83dbSDimitry Andric template <typename IndexTy> 15055ffd83dbSDimitry Andric static Type *getIndexedTypeInternal(Type *Ty, ArrayRef<IndexTy> IdxList) { 15065ffd83dbSDimitry Andric if (IdxList.empty()) 15075ffd83dbSDimitry Andric return Ty; 15085ffd83dbSDimitry Andric for (IndexTy V : IdxList.slice(1)) { 15095ffd83dbSDimitry Andric Ty = GetElementPtrInst::getTypeAtIndex(Ty, V); 15105ffd83dbSDimitry Andric if (!Ty) 15115ffd83dbSDimitry Andric return Ty; 15125ffd83dbSDimitry Andric } 15135ffd83dbSDimitry Andric return Ty; 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) { 15170b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList); 15180b57cec5SDimitry Andric } 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty, 15210b57cec5SDimitry Andric ArrayRef<Constant *> IdxList) { 15220b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList); 15230b57cec5SDimitry Andric } 15240b57cec5SDimitry Andric 15250b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList) { 15260b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList); 15270b57cec5SDimitry Andric } 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andric /// hasAllZeroIndices - Return true if all of the indices of this GEP are 15300b57cec5SDimitry Andric /// zeros. If so, the result pointer and the first operand have the same 15310b57cec5SDimitry Andric /// value, just potentially different types. 15320b57cec5SDimitry Andric bool GetElementPtrInst::hasAllZeroIndices() const { 15330b57cec5SDimitry Andric for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { 15340b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(i))) { 15350b57cec5SDimitry Andric if (!CI->isZero()) return false; 15360b57cec5SDimitry Andric } else { 15370b57cec5SDimitry Andric return false; 15380b57cec5SDimitry Andric } 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric return true; 15410b57cec5SDimitry Andric } 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric /// hasAllConstantIndices - Return true if all of the indices of this GEP are 15440b57cec5SDimitry Andric /// constant integers. If so, the result pointer and the first operand have 15450b57cec5SDimitry Andric /// a constant offset between them. 15460b57cec5SDimitry Andric bool GetElementPtrInst::hasAllConstantIndices() const { 15470b57cec5SDimitry Andric for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { 15480b57cec5SDimitry Andric if (!isa<ConstantInt>(getOperand(i))) 15490b57cec5SDimitry Andric return false; 15500b57cec5SDimitry Andric } 15510b57cec5SDimitry Andric return true; 15520b57cec5SDimitry Andric } 15530b57cec5SDimitry Andric 1554*0fca6ea1SDimitry Andric void GetElementPtrInst::setNoWrapFlags(GEPNoWrapFlags NW) { 1555*0fca6ea1SDimitry Andric SubclassOptionalData = NW.getRaw(); 1556*0fca6ea1SDimitry Andric } 1557*0fca6ea1SDimitry Andric 15580b57cec5SDimitry Andric void GetElementPtrInst::setIsInBounds(bool B) { 1559*0fca6ea1SDimitry Andric GEPNoWrapFlags NW = cast<GEPOperator>(this)->getNoWrapFlags(); 1560*0fca6ea1SDimitry Andric if (B) 1561*0fca6ea1SDimitry Andric NW |= GEPNoWrapFlags::inBounds(); 1562*0fca6ea1SDimitry Andric else 1563*0fca6ea1SDimitry Andric NW = NW.withoutInBounds(); 1564*0fca6ea1SDimitry Andric setNoWrapFlags(NW); 1565*0fca6ea1SDimitry Andric } 1566*0fca6ea1SDimitry Andric 1567*0fca6ea1SDimitry Andric GEPNoWrapFlags GetElementPtrInst::getNoWrapFlags() const { 1568*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->getNoWrapFlags(); 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric bool GetElementPtrInst::isInBounds() const { 15720b57cec5SDimitry Andric return cast<GEPOperator>(this)->isInBounds(); 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric 1575*0fca6ea1SDimitry Andric bool GetElementPtrInst::hasNoUnsignedSignedWrap() const { 1576*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->hasNoUnsignedSignedWrap(); 1577*0fca6ea1SDimitry Andric } 1578*0fca6ea1SDimitry Andric 1579*0fca6ea1SDimitry Andric bool GetElementPtrInst::hasNoUnsignedWrap() const { 1580*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->hasNoUnsignedWrap(); 1581*0fca6ea1SDimitry Andric } 1582*0fca6ea1SDimitry Andric 15830b57cec5SDimitry Andric bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL, 15840b57cec5SDimitry Andric APInt &Offset) const { 15850b57cec5SDimitry Andric // Delegate to the generic GEPOperator implementation. 15860b57cec5SDimitry Andric return cast<GEPOperator>(this)->accumulateConstantOffset(DL, Offset); 15870b57cec5SDimitry Andric } 15880b57cec5SDimitry Andric 1589fe6060f1SDimitry Andric bool GetElementPtrInst::collectOffset( 1590fe6060f1SDimitry Andric const DataLayout &DL, unsigned BitWidth, 1591fe6060f1SDimitry Andric MapVector<Value *, APInt> &VariableOffsets, 1592fe6060f1SDimitry Andric APInt &ConstantOffset) const { 1593fe6060f1SDimitry Andric // Delegate to the generic GEPOperator implementation. 1594fe6060f1SDimitry Andric return cast<GEPOperator>(this)->collectOffset(DL, BitWidth, VariableOffsets, 1595fe6060f1SDimitry Andric ConstantOffset); 1596fe6060f1SDimitry Andric } 1597fe6060f1SDimitry Andric 15980b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 15990b57cec5SDimitry Andric // ExtractElementInst Implementation 16000b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 16010b57cec5SDimitry Andric 16020b57cec5SDimitry Andric ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, 16030b57cec5SDimitry Andric const Twine &Name, 1604*0fca6ea1SDimitry Andric InsertPosition InsertBef) 1605*0fca6ea1SDimitry Andric : Instruction( 1606*0fca6ea1SDimitry Andric cast<VectorType>(Val->getType())->getElementType(), ExtractElement, 1607*0fca6ea1SDimitry Andric OperandTraits<ExtractElementInst>::op_begin(this), 2, InsertBef) { 16080b57cec5SDimitry Andric assert(isValidOperands(Val, Index) && 16090b57cec5SDimitry Andric "Invalid extractelement instruction operands!"); 16100b57cec5SDimitry Andric Op<0>() = Val; 16110b57cec5SDimitry Andric Op<1>() = Index; 16120b57cec5SDimitry Andric setName(Name); 16130b57cec5SDimitry Andric } 16140b57cec5SDimitry Andric 16150b57cec5SDimitry Andric bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) { 16160b57cec5SDimitry Andric if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy()) 16170b57cec5SDimitry Andric return false; 16180b57cec5SDimitry Andric return true; 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 16220b57cec5SDimitry Andric // InsertElementInst Implementation 16230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, 16260b57cec5SDimitry Andric const Twine &Name, 1627*0fca6ea1SDimitry Andric InsertPosition InsertBef) 16280b57cec5SDimitry Andric : Instruction(Vec->getType(), InsertElement, 1629*0fca6ea1SDimitry Andric OperandTraits<InsertElementInst>::op_begin(this), 3, 1630*0fca6ea1SDimitry Andric InsertBef) { 16310b57cec5SDimitry Andric assert(isValidOperands(Vec, Elt, Index) && 16320b57cec5SDimitry Andric "Invalid insertelement instruction operands!"); 16330b57cec5SDimitry Andric Op<0>() = Vec; 16340b57cec5SDimitry Andric Op<1>() = Elt; 16350b57cec5SDimitry Andric Op<2>() = Index; 16360b57cec5SDimitry Andric setName(Name); 16370b57cec5SDimitry Andric } 16380b57cec5SDimitry Andric 16390b57cec5SDimitry Andric bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, 16400b57cec5SDimitry Andric const Value *Index) { 16410b57cec5SDimitry Andric if (!Vec->getType()->isVectorTy()) 16420b57cec5SDimitry Andric return false; // First operand of insertelement must be vector type. 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType()) 16450b57cec5SDimitry Andric return false;// Second operand of insertelement must be vector element type. 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andric if (!Index->getType()->isIntegerTy()) 16480b57cec5SDimitry Andric return false; // Third operand of insertelement must be i32. 16490b57cec5SDimitry Andric return true; 16500b57cec5SDimitry Andric } 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 16530b57cec5SDimitry Andric // ShuffleVectorInst Implementation 16540b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 16550b57cec5SDimitry Andric 1656349cc55cSDimitry Andric static Value *createPlaceholderForShuffleVector(Value *V) { 1657349cc55cSDimitry Andric assert(V && "Cannot create placeholder of nullptr V"); 1658349cc55cSDimitry Andric return PoisonValue::get(V->getType()); 1659349cc55cSDimitry Andric } 1660349cc55cSDimitry Andric 1661349cc55cSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *Mask, const Twine &Name, 1662*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 1663349cc55cSDimitry Andric : ShuffleVectorInst(V1, createPlaceholderForShuffleVector(V1), Mask, Name, 1664349cc55cSDimitry Andric InsertBefore) {} 1665349cc55cSDimitry Andric 1666349cc55cSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, ArrayRef<int> Mask, 1667349cc55cSDimitry Andric const Twine &Name, 1668*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 1669349cc55cSDimitry Andric : ShuffleVectorInst(V1, createPlaceholderForShuffleVector(V1), Mask, Name, 1670349cc55cSDimitry Andric InsertBefore) {} 1671349cc55cSDimitry Andric 16720b57cec5SDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, 16730b57cec5SDimitry Andric const Twine &Name, 1674*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 16755ffd83dbSDimitry Andric : Instruction( 16765ffd83dbSDimitry Andric VectorType::get(cast<VectorType>(V1->getType())->getElementType(), 16778bcb0991SDimitry Andric cast<VectorType>(Mask->getType())->getElementCount()), 16785ffd83dbSDimitry Andric ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this), 16795ffd83dbSDimitry Andric OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) { 16800b57cec5SDimitry Andric assert(isValidOperands(V1, V2, Mask) && 16810b57cec5SDimitry Andric "Invalid shuffle vector instruction operands!"); 16825ffd83dbSDimitry Andric 16830b57cec5SDimitry Andric Op<0>() = V1; 16840b57cec5SDimitry Andric Op<1>() = V2; 16855ffd83dbSDimitry Andric SmallVector<int, 16> MaskArr; 16865ffd83dbSDimitry Andric getShuffleMask(cast<Constant>(Mask), MaskArr); 16875ffd83dbSDimitry Andric setShuffleMask(MaskArr); 16880b57cec5SDimitry Andric setName(Name); 16890b57cec5SDimitry Andric } 16900b57cec5SDimitry Andric 16915ffd83dbSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask, 16925ffd83dbSDimitry Andric const Twine &Name, 1693*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 16945ffd83dbSDimitry Andric : Instruction( 16955ffd83dbSDimitry Andric VectorType::get(cast<VectorType>(V1->getType())->getElementType(), 16965ffd83dbSDimitry Andric Mask.size(), isa<ScalableVectorType>(V1->getType())), 16975ffd83dbSDimitry Andric ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this), 16985ffd83dbSDimitry Andric OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) { 16995ffd83dbSDimitry Andric assert(isValidOperands(V1, V2, Mask) && 17005ffd83dbSDimitry Andric "Invalid shuffle vector instruction operands!"); 17015ffd83dbSDimitry Andric Op<0>() = V1; 17025ffd83dbSDimitry Andric Op<1>() = V2; 17035ffd83dbSDimitry Andric setShuffleMask(Mask); 17045ffd83dbSDimitry Andric setName(Name); 17055ffd83dbSDimitry Andric } 17065ffd83dbSDimitry Andric 17070b57cec5SDimitry Andric void ShuffleVectorInst::commute() { 1708e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements(); 17095ffd83dbSDimitry Andric int NumMaskElts = ShuffleMask.size(); 17105ffd83dbSDimitry Andric SmallVector<int, 16> NewMask(NumMaskElts); 17110b57cec5SDimitry Andric for (int i = 0; i != NumMaskElts; ++i) { 17120b57cec5SDimitry Andric int MaskElt = getMaskValue(i); 171306c3fb27SDimitry Andric if (MaskElt == PoisonMaskElem) { 171406c3fb27SDimitry Andric NewMask[i] = PoisonMaskElem; 17150b57cec5SDimitry Andric continue; 17160b57cec5SDimitry Andric } 17170b57cec5SDimitry Andric assert(MaskElt >= 0 && MaskElt < 2 * NumOpElts && "Out-of-range mask"); 17180b57cec5SDimitry Andric MaskElt = (MaskElt < NumOpElts) ? MaskElt + NumOpElts : MaskElt - NumOpElts; 17195ffd83dbSDimitry Andric NewMask[i] = MaskElt; 17200b57cec5SDimitry Andric } 17215ffd83dbSDimitry Andric setShuffleMask(NewMask); 17220b57cec5SDimitry Andric Op<0>().swap(Op<1>()); 17230b57cec5SDimitry Andric } 17240b57cec5SDimitry Andric 17250b57cec5SDimitry Andric bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, 17265ffd83dbSDimitry Andric ArrayRef<int> Mask) { 17275ffd83dbSDimitry Andric // V1 and V2 must be vectors of the same type. 17285ffd83dbSDimitry Andric if (!isa<VectorType>(V1->getType()) || V1->getType() != V2->getType()) 17295ffd83dbSDimitry Andric return false; 17305ffd83dbSDimitry Andric 17315ffd83dbSDimitry Andric // Make sure the mask elements make sense. 1732e8d8bef9SDimitry Andric int V1Size = 1733e8d8bef9SDimitry Andric cast<VectorType>(V1->getType())->getElementCount().getKnownMinValue(); 17345ffd83dbSDimitry Andric for (int Elem : Mask) 173506c3fb27SDimitry Andric if (Elem != PoisonMaskElem && Elem >= V1Size * 2) 17365ffd83dbSDimitry Andric return false; 17375ffd83dbSDimitry Andric 17385ffd83dbSDimitry Andric if (isa<ScalableVectorType>(V1->getType())) 173906c3fb27SDimitry Andric if ((Mask[0] != 0 && Mask[0] != PoisonMaskElem) || !all_equal(Mask)) 17405ffd83dbSDimitry Andric return false; 17415ffd83dbSDimitry Andric 17425ffd83dbSDimitry Andric return true; 17435ffd83dbSDimitry Andric } 17445ffd83dbSDimitry Andric 17455ffd83dbSDimitry Andric bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, 17460b57cec5SDimitry Andric const Value *Mask) { 17470b57cec5SDimitry Andric // V1 and V2 must be vectors of the same type. 17480b57cec5SDimitry Andric if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType()) 17490b57cec5SDimitry Andric return false; 17500b57cec5SDimitry Andric 17515ffd83dbSDimitry Andric // Mask must be vector of i32, and must be the same kind of vector as the 17525ffd83dbSDimitry Andric // input vectors 17530b57cec5SDimitry Andric auto *MaskTy = dyn_cast<VectorType>(Mask->getType()); 17545ffd83dbSDimitry Andric if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32) || 17555ffd83dbSDimitry Andric isa<ScalableVectorType>(MaskTy) != isa<ScalableVectorType>(V1->getType())) 17560b57cec5SDimitry Andric return false; 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric // Check to see if Mask is valid. 17590b57cec5SDimitry Andric if (isa<UndefValue>(Mask) || isa<ConstantAggregateZero>(Mask)) 17600b57cec5SDimitry Andric return true; 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric if (const auto *MV = dyn_cast<ConstantVector>(Mask)) { 1763e8d8bef9SDimitry Andric unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements(); 17640b57cec5SDimitry Andric for (Value *Op : MV->operands()) { 17650b57cec5SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(Op)) { 17660b57cec5SDimitry Andric if (CI->uge(V1Size*2)) 17670b57cec5SDimitry Andric return false; 17680b57cec5SDimitry Andric } else if (!isa<UndefValue>(Op)) { 17690b57cec5SDimitry Andric return false; 17700b57cec5SDimitry Andric } 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric return true; 17730b57cec5SDimitry Andric } 17740b57cec5SDimitry Andric 17750b57cec5SDimitry Andric if (const auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) { 1776e8d8bef9SDimitry Andric unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements(); 1777e8d8bef9SDimitry Andric for (unsigned i = 0, e = cast<FixedVectorType>(MaskTy)->getNumElements(); 1778e8d8bef9SDimitry Andric i != e; ++i) 17790b57cec5SDimitry Andric if (CDS->getElementAsInteger(i) >= V1Size*2) 17800b57cec5SDimitry Andric return false; 17810b57cec5SDimitry Andric return true; 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric return false; 17850b57cec5SDimitry Andric } 17860b57cec5SDimitry Andric 17870b57cec5SDimitry Andric void ShuffleVectorInst::getShuffleMask(const Constant *Mask, 17880b57cec5SDimitry Andric SmallVectorImpl<int> &Result) { 1789e8d8bef9SDimitry Andric ElementCount EC = cast<VectorType>(Mask->getType())->getElementCount(); 1790e8d8bef9SDimitry Andric 17915ffd83dbSDimitry Andric if (isa<ConstantAggregateZero>(Mask)) { 1792e8d8bef9SDimitry Andric Result.resize(EC.getKnownMinValue(), 0); 17935ffd83dbSDimitry Andric return; 17945ffd83dbSDimitry Andric } 1795e8d8bef9SDimitry Andric 1796e8d8bef9SDimitry Andric Result.reserve(EC.getKnownMinValue()); 1797e8d8bef9SDimitry Andric 1798e8d8bef9SDimitry Andric if (EC.isScalable()) { 1799e8d8bef9SDimitry Andric assert((isa<ConstantAggregateZero>(Mask) || isa<UndefValue>(Mask)) && 1800e8d8bef9SDimitry Andric "Scalable vector shuffle mask must be undef or zeroinitializer"); 1801e8d8bef9SDimitry Andric int MaskVal = isa<UndefValue>(Mask) ? -1 : 0; 1802e8d8bef9SDimitry Andric for (unsigned I = 0; I < EC.getKnownMinValue(); ++I) 1803e8d8bef9SDimitry Andric Result.emplace_back(MaskVal); 1804e8d8bef9SDimitry Andric return; 1805e8d8bef9SDimitry Andric } 1806e8d8bef9SDimitry Andric 1807e8d8bef9SDimitry Andric unsigned NumElts = EC.getKnownMinValue(); 1808e8d8bef9SDimitry Andric 18090b57cec5SDimitry Andric if (auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) { 18100b57cec5SDimitry Andric for (unsigned i = 0; i != NumElts; ++i) 18110b57cec5SDimitry Andric Result.push_back(CDS->getElementAsInteger(i)); 18120b57cec5SDimitry Andric return; 18130b57cec5SDimitry Andric } 18140b57cec5SDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 18150b57cec5SDimitry Andric Constant *C = Mask->getAggregateElement(i); 18160b57cec5SDimitry Andric Result.push_back(isa<UndefValue>(C) ? -1 : 18170b57cec5SDimitry Andric cast<ConstantInt>(C)->getZExtValue()); 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric } 18200b57cec5SDimitry Andric 18215ffd83dbSDimitry Andric void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) { 18225ffd83dbSDimitry Andric ShuffleMask.assign(Mask.begin(), Mask.end()); 18235ffd83dbSDimitry Andric ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType()); 18245ffd83dbSDimitry Andric } 1825fe6060f1SDimitry Andric 18265ffd83dbSDimitry Andric Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask, 18275ffd83dbSDimitry Andric Type *ResultTy) { 18285ffd83dbSDimitry Andric Type *Int32Ty = Type::getInt32Ty(ResultTy->getContext()); 18295ffd83dbSDimitry Andric if (isa<ScalableVectorType>(ResultTy)) { 1830bdd1243dSDimitry Andric assert(all_equal(Mask) && "Unexpected shuffle"); 18315ffd83dbSDimitry Andric Type *VecTy = VectorType::get(Int32Ty, Mask.size(), true); 18325ffd83dbSDimitry Andric if (Mask[0] == 0) 18335ffd83dbSDimitry Andric return Constant::getNullValue(VecTy); 1834*0fca6ea1SDimitry Andric return PoisonValue::get(VecTy); 18355ffd83dbSDimitry Andric } 18365ffd83dbSDimitry Andric SmallVector<Constant *, 16> MaskConst; 18375ffd83dbSDimitry Andric for (int Elem : Mask) { 183806c3fb27SDimitry Andric if (Elem == PoisonMaskElem) 183906c3fb27SDimitry Andric MaskConst.push_back(PoisonValue::get(Int32Ty)); 18405ffd83dbSDimitry Andric else 18415ffd83dbSDimitry Andric MaskConst.push_back(ConstantInt::get(Int32Ty, Elem)); 18425ffd83dbSDimitry Andric } 18435ffd83dbSDimitry Andric return ConstantVector::get(MaskConst); 18445ffd83dbSDimitry Andric } 18455ffd83dbSDimitry Andric 18460b57cec5SDimitry Andric static bool isSingleSourceMaskImpl(ArrayRef<int> Mask, int NumOpElts) { 18470b57cec5SDimitry Andric assert(!Mask.empty() && "Shuffle mask must contain elements"); 18480b57cec5SDimitry Andric bool UsesLHS = false; 18490b57cec5SDimitry Andric bool UsesRHS = false; 1850fe6060f1SDimitry Andric for (int I : Mask) { 1851fe6060f1SDimitry Andric if (I == -1) 18520b57cec5SDimitry Andric continue; 1853fe6060f1SDimitry Andric assert(I >= 0 && I < (NumOpElts * 2) && 18540b57cec5SDimitry Andric "Out-of-bounds shuffle mask element"); 1855fe6060f1SDimitry Andric UsesLHS |= (I < NumOpElts); 1856fe6060f1SDimitry Andric UsesRHS |= (I >= NumOpElts); 18570b57cec5SDimitry Andric if (UsesLHS && UsesRHS) 18580b57cec5SDimitry Andric return false; 18590b57cec5SDimitry Andric } 18605ffd83dbSDimitry Andric // Allow for degenerate case: completely undef mask means neither source is used. 18615ffd83dbSDimitry Andric return UsesLHS || UsesRHS; 18620b57cec5SDimitry Andric } 18630b57cec5SDimitry Andric 18645f757f3fSDimitry Andric bool ShuffleVectorInst::isSingleSourceMask(ArrayRef<int> Mask, int NumSrcElts) { 18650b57cec5SDimitry Andric // We don't have vector operand size information, so assume operands are the 18660b57cec5SDimitry Andric // same size as the mask. 18675f757f3fSDimitry Andric return isSingleSourceMaskImpl(Mask, NumSrcElts); 18680b57cec5SDimitry Andric } 18690b57cec5SDimitry Andric 18700b57cec5SDimitry Andric static bool isIdentityMaskImpl(ArrayRef<int> Mask, int NumOpElts) { 18710b57cec5SDimitry Andric if (!isSingleSourceMaskImpl(Mask, NumOpElts)) 18720b57cec5SDimitry Andric return false; 18730b57cec5SDimitry Andric for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) { 18740b57cec5SDimitry Andric if (Mask[i] == -1) 18750b57cec5SDimitry Andric continue; 18760b57cec5SDimitry Andric if (Mask[i] != i && Mask[i] != (NumOpElts + i)) 18770b57cec5SDimitry Andric return false; 18780b57cec5SDimitry Andric } 18790b57cec5SDimitry Andric return true; 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric 18825f757f3fSDimitry Andric bool ShuffleVectorInst::isIdentityMask(ArrayRef<int> Mask, int NumSrcElts) { 18835f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 18845f757f3fSDimitry Andric return false; 18850b57cec5SDimitry Andric // We don't have vector operand size information, so assume operands are the 18860b57cec5SDimitry Andric // same size as the mask. 18875f757f3fSDimitry Andric return isIdentityMaskImpl(Mask, NumSrcElts); 18880b57cec5SDimitry Andric } 18890b57cec5SDimitry Andric 18905f757f3fSDimitry Andric bool ShuffleVectorInst::isReverseMask(ArrayRef<int> Mask, int NumSrcElts) { 18915f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 18925f757f3fSDimitry Andric return false; 18935f757f3fSDimitry Andric if (!isSingleSourceMask(Mask, NumSrcElts)) 18940b57cec5SDimitry Andric return false; 189581ad6265SDimitry Andric 189681ad6265SDimitry Andric // The number of elements in the mask must be at least 2. 18975f757f3fSDimitry Andric if (NumSrcElts < 2) 189881ad6265SDimitry Andric return false; 189981ad6265SDimitry Andric 19005f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) { 19015f757f3fSDimitry Andric if (Mask[I] == -1) 19020b57cec5SDimitry Andric continue; 19035f757f3fSDimitry Andric if (Mask[I] != (NumSrcElts - 1 - I) && 19045f757f3fSDimitry Andric Mask[I] != (NumSrcElts + NumSrcElts - 1 - I)) 19050b57cec5SDimitry Andric return false; 19060b57cec5SDimitry Andric } 19070b57cec5SDimitry Andric return true; 19080b57cec5SDimitry Andric } 19090b57cec5SDimitry Andric 19105f757f3fSDimitry Andric bool ShuffleVectorInst::isZeroEltSplatMask(ArrayRef<int> Mask, int NumSrcElts) { 19115f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 19120b57cec5SDimitry Andric return false; 19135f757f3fSDimitry Andric if (!isSingleSourceMask(Mask, NumSrcElts)) 19145f757f3fSDimitry Andric return false; 19155f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) { 19165f757f3fSDimitry Andric if (Mask[I] == -1) 19170b57cec5SDimitry Andric continue; 19185f757f3fSDimitry Andric if (Mask[I] != 0 && Mask[I] != NumSrcElts) 19190b57cec5SDimitry Andric return false; 19200b57cec5SDimitry Andric } 19210b57cec5SDimitry Andric return true; 19220b57cec5SDimitry Andric } 19230b57cec5SDimitry Andric 19245f757f3fSDimitry Andric bool ShuffleVectorInst::isSelectMask(ArrayRef<int> Mask, int NumSrcElts) { 19255f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 19265f757f3fSDimitry Andric return false; 19270b57cec5SDimitry Andric // Select is differentiated from identity. It requires using both sources. 19285f757f3fSDimitry Andric if (isSingleSourceMask(Mask, NumSrcElts)) 19290b57cec5SDimitry Andric return false; 19305f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) { 19315f757f3fSDimitry Andric if (Mask[I] == -1) 19320b57cec5SDimitry Andric continue; 19335f757f3fSDimitry Andric if (Mask[I] != I && Mask[I] != (NumSrcElts + I)) 19340b57cec5SDimitry Andric return false; 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric return true; 19370b57cec5SDimitry Andric } 19380b57cec5SDimitry Andric 19395f757f3fSDimitry Andric bool ShuffleVectorInst::isTransposeMask(ArrayRef<int> Mask, int NumSrcElts) { 19400b57cec5SDimitry Andric // Example masks that will return true: 19410b57cec5SDimitry Andric // v1 = <a, b, c, d> 19420b57cec5SDimitry Andric // v2 = <e, f, g, h> 19430b57cec5SDimitry Andric // trn1 = shufflevector v1, v2 <0, 4, 2, 6> = <a, e, c, g> 19440b57cec5SDimitry Andric // trn2 = shufflevector v1, v2 <1, 5, 3, 7> = <b, f, d, h> 19450b57cec5SDimitry Andric 19465f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 19475f757f3fSDimitry Andric return false; 19480b57cec5SDimitry Andric // 1. The number of elements in the mask must be a power-of-2 and at least 2. 19495f757f3fSDimitry Andric int Sz = Mask.size(); 19505f757f3fSDimitry Andric if (Sz < 2 || !isPowerOf2_32(Sz)) 19510b57cec5SDimitry Andric return false; 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric // 2. The first element of the mask must be either a 0 or a 1. 19540b57cec5SDimitry Andric if (Mask[0] != 0 && Mask[0] != 1) 19550b57cec5SDimitry Andric return false; 19560b57cec5SDimitry Andric 19570b57cec5SDimitry Andric // 3. The difference between the first 2 elements must be equal to the 19580b57cec5SDimitry Andric // number of elements in the mask. 19595f757f3fSDimitry Andric if ((Mask[1] - Mask[0]) != NumSrcElts) 19600b57cec5SDimitry Andric return false; 19610b57cec5SDimitry Andric 19620b57cec5SDimitry Andric // 4. The difference between consecutive even-numbered and odd-numbered 19630b57cec5SDimitry Andric // elements must be equal to 2. 19645f757f3fSDimitry Andric for (int I = 2; I < Sz; ++I) { 19655f757f3fSDimitry Andric int MaskEltVal = Mask[I]; 19660b57cec5SDimitry Andric if (MaskEltVal == -1) 19670b57cec5SDimitry Andric return false; 19685f757f3fSDimitry Andric int MaskEltPrevVal = Mask[I - 2]; 19690b57cec5SDimitry Andric if (MaskEltVal - MaskEltPrevVal != 2) 19700b57cec5SDimitry Andric return false; 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric return true; 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric 19755f757f3fSDimitry Andric bool ShuffleVectorInst::isSpliceMask(ArrayRef<int> Mask, int NumSrcElts, 19765f757f3fSDimitry Andric int &Index) { 19775f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts)) 19785f757f3fSDimitry Andric return false; 1979bdd1243dSDimitry Andric // Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4> 1980bdd1243dSDimitry Andric int StartIndex = -1; 1981bdd1243dSDimitry Andric for (int I = 0, E = Mask.size(); I != E; ++I) { 1982bdd1243dSDimitry Andric int MaskEltVal = Mask[I]; 1983bdd1243dSDimitry Andric if (MaskEltVal == -1) 1984bdd1243dSDimitry Andric continue; 1985bdd1243dSDimitry Andric 1986bdd1243dSDimitry Andric if (StartIndex == -1) { 1987bdd1243dSDimitry Andric // Don't support a StartIndex that begins in the second input, or if the 1988bdd1243dSDimitry Andric // first non-undef index would access below the StartIndex. 19895f757f3fSDimitry Andric if (MaskEltVal < I || NumSrcElts <= (MaskEltVal - I)) 1990bdd1243dSDimitry Andric return false; 1991bdd1243dSDimitry Andric 1992bdd1243dSDimitry Andric StartIndex = MaskEltVal - I; 1993bdd1243dSDimitry Andric continue; 1994bdd1243dSDimitry Andric } 1995bdd1243dSDimitry Andric 1996bdd1243dSDimitry Andric // Splice is sequential starting from StartIndex. 1997bdd1243dSDimitry Andric if (MaskEltVal != (StartIndex + I)) 1998bdd1243dSDimitry Andric return false; 1999bdd1243dSDimitry Andric } 2000bdd1243dSDimitry Andric 2001bdd1243dSDimitry Andric if (StartIndex == -1) 2002bdd1243dSDimitry Andric return false; 2003bdd1243dSDimitry Andric 2004bdd1243dSDimitry Andric // NOTE: This accepts StartIndex == 0 (COPY). 2005bdd1243dSDimitry Andric Index = StartIndex; 2006bdd1243dSDimitry Andric return true; 2007bdd1243dSDimitry Andric } 2008bdd1243dSDimitry Andric 20090b57cec5SDimitry Andric bool ShuffleVectorInst::isExtractSubvectorMask(ArrayRef<int> Mask, 20100b57cec5SDimitry Andric int NumSrcElts, int &Index) { 20110b57cec5SDimitry Andric // Must extract from a single source. 20120b57cec5SDimitry Andric if (!isSingleSourceMaskImpl(Mask, NumSrcElts)) 20130b57cec5SDimitry Andric return false; 20140b57cec5SDimitry Andric 20150b57cec5SDimitry Andric // Must be smaller (else this is an Identity shuffle). 20160b57cec5SDimitry Andric if (NumSrcElts <= (int)Mask.size()) 20170b57cec5SDimitry Andric return false; 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric // Find start of extraction, accounting that we may start with an UNDEF. 20200b57cec5SDimitry Andric int SubIndex = -1; 20210b57cec5SDimitry Andric for (int i = 0, e = Mask.size(); i != e; ++i) { 20220b57cec5SDimitry Andric int M = Mask[i]; 20230b57cec5SDimitry Andric if (M < 0) 20240b57cec5SDimitry Andric continue; 20250b57cec5SDimitry Andric int Offset = (M % NumSrcElts) - i; 20260b57cec5SDimitry Andric if (0 <= SubIndex && SubIndex != Offset) 20270b57cec5SDimitry Andric return false; 20280b57cec5SDimitry Andric SubIndex = Offset; 20290b57cec5SDimitry Andric } 20300b57cec5SDimitry Andric 2031480093f4SDimitry Andric if (0 <= SubIndex && SubIndex + (int)Mask.size() <= NumSrcElts) { 20320b57cec5SDimitry Andric Index = SubIndex; 20330b57cec5SDimitry Andric return true; 20340b57cec5SDimitry Andric } 20350b57cec5SDimitry Andric return false; 20360b57cec5SDimitry Andric } 20370b57cec5SDimitry Andric 2038349cc55cSDimitry Andric bool ShuffleVectorInst::isInsertSubvectorMask(ArrayRef<int> Mask, 2039349cc55cSDimitry Andric int NumSrcElts, int &NumSubElts, 2040349cc55cSDimitry Andric int &Index) { 2041349cc55cSDimitry Andric int NumMaskElts = Mask.size(); 2042349cc55cSDimitry Andric 2043349cc55cSDimitry Andric // Don't try to match if we're shuffling to a smaller size. 2044349cc55cSDimitry Andric if (NumMaskElts < NumSrcElts) 2045349cc55cSDimitry Andric return false; 2046349cc55cSDimitry Andric 2047349cc55cSDimitry Andric // TODO: We don't recognize self-insertion/widening. 2048349cc55cSDimitry Andric if (isSingleSourceMaskImpl(Mask, NumSrcElts)) 2049349cc55cSDimitry Andric return false; 2050349cc55cSDimitry Andric 2051349cc55cSDimitry Andric // Determine which mask elements are attributed to which source. 2052349cc55cSDimitry Andric APInt UndefElts = APInt::getZero(NumMaskElts); 2053349cc55cSDimitry Andric APInt Src0Elts = APInt::getZero(NumMaskElts); 2054349cc55cSDimitry Andric APInt Src1Elts = APInt::getZero(NumMaskElts); 2055349cc55cSDimitry Andric bool Src0Identity = true; 2056349cc55cSDimitry Andric bool Src1Identity = true; 2057349cc55cSDimitry Andric 2058349cc55cSDimitry Andric for (int i = 0; i != NumMaskElts; ++i) { 2059349cc55cSDimitry Andric int M = Mask[i]; 2060349cc55cSDimitry Andric if (M < 0) { 2061349cc55cSDimitry Andric UndefElts.setBit(i); 2062349cc55cSDimitry Andric continue; 2063349cc55cSDimitry Andric } 2064349cc55cSDimitry Andric if (M < NumSrcElts) { 2065349cc55cSDimitry Andric Src0Elts.setBit(i); 2066349cc55cSDimitry Andric Src0Identity &= (M == i); 2067349cc55cSDimitry Andric continue; 2068349cc55cSDimitry Andric } 2069349cc55cSDimitry Andric Src1Elts.setBit(i); 2070349cc55cSDimitry Andric Src1Identity &= (M == (i + NumSrcElts)); 2071349cc55cSDimitry Andric } 2072349cc55cSDimitry Andric assert((Src0Elts | Src1Elts | UndefElts).isAllOnes() && 2073349cc55cSDimitry Andric "unknown shuffle elements"); 2074349cc55cSDimitry Andric assert(!Src0Elts.isZero() && !Src1Elts.isZero() && 2075349cc55cSDimitry Andric "2-source shuffle not found"); 2076349cc55cSDimitry Andric 2077349cc55cSDimitry Andric // Determine lo/hi span ranges. 2078349cc55cSDimitry Andric // TODO: How should we handle undefs at the start of subvector insertions? 207906c3fb27SDimitry Andric int Src0Lo = Src0Elts.countr_zero(); 208006c3fb27SDimitry Andric int Src1Lo = Src1Elts.countr_zero(); 208106c3fb27SDimitry Andric int Src0Hi = NumMaskElts - Src0Elts.countl_zero(); 208206c3fb27SDimitry Andric int Src1Hi = NumMaskElts - Src1Elts.countl_zero(); 2083349cc55cSDimitry Andric 2084349cc55cSDimitry Andric // If src0 is in place, see if the src1 elements is inplace within its own 2085349cc55cSDimitry Andric // span. 2086349cc55cSDimitry Andric if (Src0Identity) { 2087349cc55cSDimitry Andric int NumSub1Elts = Src1Hi - Src1Lo; 2088349cc55cSDimitry Andric ArrayRef<int> Sub1Mask = Mask.slice(Src1Lo, NumSub1Elts); 2089349cc55cSDimitry Andric if (isIdentityMaskImpl(Sub1Mask, NumSrcElts)) { 2090349cc55cSDimitry Andric NumSubElts = NumSub1Elts; 2091349cc55cSDimitry Andric Index = Src1Lo; 2092349cc55cSDimitry Andric return true; 2093349cc55cSDimitry Andric } 2094349cc55cSDimitry Andric } 2095349cc55cSDimitry Andric 2096349cc55cSDimitry Andric // If src1 is in place, see if the src0 elements is inplace within its own 2097349cc55cSDimitry Andric // span. 2098349cc55cSDimitry Andric if (Src1Identity) { 2099349cc55cSDimitry Andric int NumSub0Elts = Src0Hi - Src0Lo; 2100349cc55cSDimitry Andric ArrayRef<int> Sub0Mask = Mask.slice(Src0Lo, NumSub0Elts); 2101349cc55cSDimitry Andric if (isIdentityMaskImpl(Sub0Mask, NumSrcElts)) { 2102349cc55cSDimitry Andric NumSubElts = NumSub0Elts; 2103349cc55cSDimitry Andric Index = Src0Lo; 2104349cc55cSDimitry Andric return true; 2105349cc55cSDimitry Andric } 2106349cc55cSDimitry Andric } 2107349cc55cSDimitry Andric 2108349cc55cSDimitry Andric return false; 2109349cc55cSDimitry Andric } 2110349cc55cSDimitry Andric 21110b57cec5SDimitry Andric bool ShuffleVectorInst::isIdentityWithPadding() const { 2112e8d8bef9SDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable 2113e8d8bef9SDimitry Andric // vector for this case. 2114e8d8bef9SDimitry Andric if (isa<ScalableVectorType>(getType())) 2115e8d8bef9SDimitry Andric return false; 2116e8d8bef9SDimitry Andric 2117e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements(); 2118e8d8bef9SDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements(); 21190b57cec5SDimitry Andric if (NumMaskElts <= NumOpElts) 21200b57cec5SDimitry Andric return false; 21210b57cec5SDimitry Andric 21220b57cec5SDimitry Andric // The first part of the mask must choose elements from exactly 1 source op. 21235ffd83dbSDimitry Andric ArrayRef<int> Mask = getShuffleMask(); 21240b57cec5SDimitry Andric if (!isIdentityMaskImpl(Mask, NumOpElts)) 21250b57cec5SDimitry Andric return false; 21260b57cec5SDimitry Andric 21270b57cec5SDimitry Andric // All extending must be with undef elements. 21280b57cec5SDimitry Andric for (int i = NumOpElts; i < NumMaskElts; ++i) 21290b57cec5SDimitry Andric if (Mask[i] != -1) 21300b57cec5SDimitry Andric return false; 21310b57cec5SDimitry Andric 21320b57cec5SDimitry Andric return true; 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric bool ShuffleVectorInst::isIdentityWithExtract() const { 21365ffd83dbSDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable 2137e8d8bef9SDimitry Andric // vector for this case. 21385ffd83dbSDimitry Andric if (isa<ScalableVectorType>(getType())) 21395ffd83dbSDimitry Andric return false; 21405ffd83dbSDimitry Andric 21415ffd83dbSDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements(); 21425ffd83dbSDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements(); 21430b57cec5SDimitry Andric if (NumMaskElts >= NumOpElts) 21440b57cec5SDimitry Andric return false; 21450b57cec5SDimitry Andric 21460b57cec5SDimitry Andric return isIdentityMaskImpl(getShuffleMask(), NumOpElts); 21470b57cec5SDimitry Andric } 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric bool ShuffleVectorInst::isConcat() const { 21500b57cec5SDimitry Andric // Vector concatenation is differentiated from identity with padding. 21515f757f3fSDimitry Andric if (isa<UndefValue>(Op<0>()) || isa<UndefValue>(Op<1>())) 21520b57cec5SDimitry Andric return false; 21530b57cec5SDimitry Andric 2154e8d8bef9SDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable 2155e8d8bef9SDimitry Andric // vector for this case. 2156e8d8bef9SDimitry Andric if (isa<ScalableVectorType>(getType())) 2157e8d8bef9SDimitry Andric return false; 2158e8d8bef9SDimitry Andric 2159e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements(); 2160e8d8bef9SDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements(); 21610b57cec5SDimitry Andric if (NumMaskElts != NumOpElts * 2) 21620b57cec5SDimitry Andric return false; 21630b57cec5SDimitry Andric 21640b57cec5SDimitry Andric // Use the mask length rather than the operands' vector lengths here. We 21650b57cec5SDimitry Andric // already know that the shuffle returns a vector twice as long as the inputs, 21660b57cec5SDimitry Andric // and neither of the inputs are undef vectors. If the mask picks consecutive 21670b57cec5SDimitry Andric // elements from both inputs, then this is a concatenation of the inputs. 21680b57cec5SDimitry Andric return isIdentityMaskImpl(getShuffleMask(), NumMaskElts); 21690b57cec5SDimitry Andric } 21700b57cec5SDimitry Andric 2171349cc55cSDimitry Andric static bool isReplicationMaskWithParams(ArrayRef<int> Mask, 2172349cc55cSDimitry Andric int ReplicationFactor, int VF) { 2173349cc55cSDimitry Andric assert(Mask.size() == (unsigned)ReplicationFactor * VF && 2174349cc55cSDimitry Andric "Unexpected mask size."); 2175349cc55cSDimitry Andric 21765f757f3fSDimitry Andric for (int CurrElt : seq(VF)) { 2177349cc55cSDimitry Andric ArrayRef<int> CurrSubMask = Mask.take_front(ReplicationFactor); 2178349cc55cSDimitry Andric assert(CurrSubMask.size() == (unsigned)ReplicationFactor && 2179349cc55cSDimitry Andric "Run out of mask?"); 2180349cc55cSDimitry Andric Mask = Mask.drop_front(ReplicationFactor); 2181349cc55cSDimitry Andric if (!all_of(CurrSubMask, [CurrElt](int MaskElt) { 218206c3fb27SDimitry Andric return MaskElt == PoisonMaskElem || MaskElt == CurrElt; 2183349cc55cSDimitry Andric })) 2184349cc55cSDimitry Andric return false; 2185349cc55cSDimitry Andric } 2186349cc55cSDimitry Andric assert(Mask.empty() && "Did not consume the whole mask?"); 2187349cc55cSDimitry Andric 2188349cc55cSDimitry Andric return true; 2189349cc55cSDimitry Andric } 2190349cc55cSDimitry Andric 2191349cc55cSDimitry Andric bool ShuffleVectorInst::isReplicationMask(ArrayRef<int> Mask, 2192349cc55cSDimitry Andric int &ReplicationFactor, int &VF) { 2193349cc55cSDimitry Andric // undef-less case is trivial. 219406c3fb27SDimitry Andric if (!llvm::is_contained(Mask, PoisonMaskElem)) { 2195349cc55cSDimitry Andric ReplicationFactor = 2196349cc55cSDimitry Andric Mask.take_while([](int MaskElt) { return MaskElt == 0; }).size(); 2197349cc55cSDimitry Andric if (ReplicationFactor == 0 || Mask.size() % ReplicationFactor != 0) 2198349cc55cSDimitry Andric return false; 2199349cc55cSDimitry Andric VF = Mask.size() / ReplicationFactor; 2200349cc55cSDimitry Andric return isReplicationMaskWithParams(Mask, ReplicationFactor, VF); 2201349cc55cSDimitry Andric } 2202349cc55cSDimitry Andric 2203349cc55cSDimitry Andric // However, if the mask contains undef's, we have to enumerate possible tuples 2204349cc55cSDimitry Andric // and pick one. There are bounds on replication factor: [1, mask size] 2205349cc55cSDimitry Andric // (where RF=1 is an identity shuffle, RF=mask size is a broadcast shuffle) 2206349cc55cSDimitry Andric // Additionally, mask size is a replication factor multiplied by vector size, 2207349cc55cSDimitry Andric // which further significantly reduces the search space. 2208349cc55cSDimitry Andric 22094824e7fdSDimitry Andric // Before doing that, let's perform basic correctness checking first. 2210349cc55cSDimitry Andric int Largest = -1; 2211349cc55cSDimitry Andric for (int MaskElt : Mask) { 221206c3fb27SDimitry Andric if (MaskElt == PoisonMaskElem) 2213349cc55cSDimitry Andric continue; 2214349cc55cSDimitry Andric // Elements must be in non-decreasing order. 2215349cc55cSDimitry Andric if (MaskElt < Largest) 2216349cc55cSDimitry Andric return false; 2217349cc55cSDimitry Andric Largest = std::max(Largest, MaskElt); 2218349cc55cSDimitry Andric } 2219349cc55cSDimitry Andric 2220349cc55cSDimitry Andric // Prefer larger replication factor if all else equal. 2221349cc55cSDimitry Andric for (int PossibleReplicationFactor : 2222349cc55cSDimitry Andric reverse(seq_inclusive<unsigned>(1, Mask.size()))) { 2223349cc55cSDimitry Andric if (Mask.size() % PossibleReplicationFactor != 0) 2224349cc55cSDimitry Andric continue; 2225349cc55cSDimitry Andric int PossibleVF = Mask.size() / PossibleReplicationFactor; 2226349cc55cSDimitry Andric if (!isReplicationMaskWithParams(Mask, PossibleReplicationFactor, 2227349cc55cSDimitry Andric PossibleVF)) 2228349cc55cSDimitry Andric continue; 2229349cc55cSDimitry Andric ReplicationFactor = PossibleReplicationFactor; 2230349cc55cSDimitry Andric VF = PossibleVF; 2231349cc55cSDimitry Andric return true; 2232349cc55cSDimitry Andric } 2233349cc55cSDimitry Andric 2234349cc55cSDimitry Andric return false; 2235349cc55cSDimitry Andric } 2236349cc55cSDimitry Andric 2237349cc55cSDimitry Andric bool ShuffleVectorInst::isReplicationMask(int &ReplicationFactor, 2238349cc55cSDimitry Andric int &VF) const { 2239349cc55cSDimitry Andric // Not possible to express a shuffle mask for a scalable vector for this 2240349cc55cSDimitry Andric // case. 2241349cc55cSDimitry Andric if (isa<ScalableVectorType>(getType())) 2242349cc55cSDimitry Andric return false; 2243349cc55cSDimitry Andric 2244349cc55cSDimitry Andric VF = cast<FixedVectorType>(Op<0>()->getType())->getNumElements(); 2245349cc55cSDimitry Andric if (ShuffleMask.size() % VF != 0) 2246349cc55cSDimitry Andric return false; 2247349cc55cSDimitry Andric ReplicationFactor = ShuffleMask.size() / VF; 2248349cc55cSDimitry Andric 2249349cc55cSDimitry Andric return isReplicationMaskWithParams(ShuffleMask, ReplicationFactor, VF); 2250349cc55cSDimitry Andric } 2251349cc55cSDimitry Andric 2252bdd1243dSDimitry Andric bool ShuffleVectorInst::isOneUseSingleSourceMask(ArrayRef<int> Mask, int VF) { 2253bdd1243dSDimitry Andric if (VF <= 0 || Mask.size() < static_cast<unsigned>(VF) || 2254bdd1243dSDimitry Andric Mask.size() % VF != 0) 2255bdd1243dSDimitry Andric return false; 2256bdd1243dSDimitry Andric for (unsigned K = 0, Sz = Mask.size(); K < Sz; K += VF) { 2257bdd1243dSDimitry Andric ArrayRef<int> SubMask = Mask.slice(K, VF); 225806c3fb27SDimitry Andric if (all_of(SubMask, [](int Idx) { return Idx == PoisonMaskElem; })) 2259bdd1243dSDimitry Andric continue; 2260bdd1243dSDimitry Andric SmallBitVector Used(VF, false); 22615f757f3fSDimitry Andric for (int Idx : SubMask) { 226206c3fb27SDimitry Andric if (Idx != PoisonMaskElem && Idx < VF) 2263bdd1243dSDimitry Andric Used.set(Idx); 22645f757f3fSDimitry Andric } 2265bdd1243dSDimitry Andric if (!Used.all()) 2266bdd1243dSDimitry Andric return false; 2267bdd1243dSDimitry Andric } 2268bdd1243dSDimitry Andric return true; 2269bdd1243dSDimitry Andric } 2270bdd1243dSDimitry Andric 2271bdd1243dSDimitry Andric /// Return true if this shuffle mask is a replication mask. 2272bdd1243dSDimitry Andric bool ShuffleVectorInst::isOneUseSingleSourceMask(int VF) const { 2273bdd1243dSDimitry Andric // Not possible to express a shuffle mask for a scalable vector for this 2274bdd1243dSDimitry Andric // case. 2275bdd1243dSDimitry Andric if (isa<ScalableVectorType>(getType())) 2276bdd1243dSDimitry Andric return false; 22775f757f3fSDimitry Andric if (!isSingleSourceMask(ShuffleMask, VF)) 2278bdd1243dSDimitry Andric return false; 2279bdd1243dSDimitry Andric 2280bdd1243dSDimitry Andric return isOneUseSingleSourceMask(ShuffleMask, VF); 2281bdd1243dSDimitry Andric } 2282bdd1243dSDimitry Andric 228306c3fb27SDimitry Andric bool ShuffleVectorInst::isInterleave(unsigned Factor) { 228406c3fb27SDimitry Andric FixedVectorType *OpTy = dyn_cast<FixedVectorType>(getOperand(0)->getType()); 228506c3fb27SDimitry Andric // shuffle_vector can only interleave fixed length vectors - for scalable 2286*0fca6ea1SDimitry Andric // vectors, see the @llvm.vector.interleave2 intrinsic 228706c3fb27SDimitry Andric if (!OpTy) 228806c3fb27SDimitry Andric return false; 228906c3fb27SDimitry Andric unsigned OpNumElts = OpTy->getNumElements(); 229006c3fb27SDimitry Andric 229106c3fb27SDimitry Andric return isInterleaveMask(ShuffleMask, Factor, OpNumElts * 2); 229206c3fb27SDimitry Andric } 229306c3fb27SDimitry Andric 229406c3fb27SDimitry Andric bool ShuffleVectorInst::isInterleaveMask( 229506c3fb27SDimitry Andric ArrayRef<int> Mask, unsigned Factor, unsigned NumInputElts, 229606c3fb27SDimitry Andric SmallVectorImpl<unsigned> &StartIndexes) { 229706c3fb27SDimitry Andric unsigned NumElts = Mask.size(); 229806c3fb27SDimitry Andric if (NumElts % Factor) 229906c3fb27SDimitry Andric return false; 230006c3fb27SDimitry Andric 230106c3fb27SDimitry Andric unsigned LaneLen = NumElts / Factor; 230206c3fb27SDimitry Andric if (!isPowerOf2_32(LaneLen)) 230306c3fb27SDimitry Andric return false; 230406c3fb27SDimitry Andric 230506c3fb27SDimitry Andric StartIndexes.resize(Factor); 230606c3fb27SDimitry Andric 230706c3fb27SDimitry Andric // Check whether each element matches the general interleaved rule. 230806c3fb27SDimitry Andric // Ignore undef elements, as long as the defined elements match the rule. 230906c3fb27SDimitry Andric // Outer loop processes all factors (x, y, z in the above example) 231006c3fb27SDimitry Andric unsigned I = 0, J; 231106c3fb27SDimitry Andric for (; I < Factor; I++) { 231206c3fb27SDimitry Andric unsigned SavedLaneValue; 231306c3fb27SDimitry Andric unsigned SavedNoUndefs = 0; 231406c3fb27SDimitry Andric 231506c3fb27SDimitry Andric // Inner loop processes consecutive accesses (x, x+1... in the example) 231606c3fb27SDimitry Andric for (J = 0; J < LaneLen - 1; J++) { 231706c3fb27SDimitry Andric // Lane computes x's position in the Mask 231806c3fb27SDimitry Andric unsigned Lane = J * Factor + I; 231906c3fb27SDimitry Andric unsigned NextLane = Lane + Factor; 232006c3fb27SDimitry Andric int LaneValue = Mask[Lane]; 232106c3fb27SDimitry Andric int NextLaneValue = Mask[NextLane]; 232206c3fb27SDimitry Andric 232306c3fb27SDimitry Andric // If both are defined, values must be sequential 232406c3fb27SDimitry Andric if (LaneValue >= 0 && NextLaneValue >= 0 && 232506c3fb27SDimitry Andric LaneValue + 1 != NextLaneValue) 232606c3fb27SDimitry Andric break; 232706c3fb27SDimitry Andric 232806c3fb27SDimitry Andric // If the next value is undef, save the current one as reference 232906c3fb27SDimitry Andric if (LaneValue >= 0 && NextLaneValue < 0) { 233006c3fb27SDimitry Andric SavedLaneValue = LaneValue; 233106c3fb27SDimitry Andric SavedNoUndefs = 1; 233206c3fb27SDimitry Andric } 233306c3fb27SDimitry Andric 233406c3fb27SDimitry Andric // Undefs are allowed, but defined elements must still be consecutive: 233506c3fb27SDimitry Andric // i.e.: x,..., undef,..., x + 2,..., undef,..., undef,..., x + 5, .... 233606c3fb27SDimitry Andric // Verify this by storing the last non-undef followed by an undef 233706c3fb27SDimitry Andric // Check that following non-undef masks are incremented with the 233806c3fb27SDimitry Andric // corresponding distance. 233906c3fb27SDimitry Andric if (SavedNoUndefs > 0 && LaneValue < 0) { 234006c3fb27SDimitry Andric SavedNoUndefs++; 234106c3fb27SDimitry Andric if (NextLaneValue >= 0 && 234206c3fb27SDimitry Andric SavedLaneValue + SavedNoUndefs != (unsigned)NextLaneValue) 234306c3fb27SDimitry Andric break; 234406c3fb27SDimitry Andric } 234506c3fb27SDimitry Andric } 234606c3fb27SDimitry Andric 234706c3fb27SDimitry Andric if (J < LaneLen - 1) 234806c3fb27SDimitry Andric return false; 234906c3fb27SDimitry Andric 235006c3fb27SDimitry Andric int StartMask = 0; 235106c3fb27SDimitry Andric if (Mask[I] >= 0) { 235206c3fb27SDimitry Andric // Check that the start of the I range (J=0) is greater than 0 235306c3fb27SDimitry Andric StartMask = Mask[I]; 235406c3fb27SDimitry Andric } else if (Mask[(LaneLen - 1) * Factor + I] >= 0) { 235506c3fb27SDimitry Andric // StartMask defined by the last value in lane 235606c3fb27SDimitry Andric StartMask = Mask[(LaneLen - 1) * Factor + I] - J; 235706c3fb27SDimitry Andric } else if (SavedNoUndefs > 0) { 235806c3fb27SDimitry Andric // StartMask defined by some non-zero value in the j loop 235906c3fb27SDimitry Andric StartMask = SavedLaneValue - (LaneLen - 1 - SavedNoUndefs); 236006c3fb27SDimitry Andric } 236106c3fb27SDimitry Andric // else StartMask remains set to 0, i.e. all elements are undefs 236206c3fb27SDimitry Andric 236306c3fb27SDimitry Andric if (StartMask < 0) 236406c3fb27SDimitry Andric return false; 236506c3fb27SDimitry Andric // We must stay within the vectors; This case can happen with undefs. 236606c3fb27SDimitry Andric if (StartMask + LaneLen > NumInputElts) 236706c3fb27SDimitry Andric return false; 236806c3fb27SDimitry Andric 236906c3fb27SDimitry Andric StartIndexes[I] = StartMask; 237006c3fb27SDimitry Andric } 237106c3fb27SDimitry Andric 237206c3fb27SDimitry Andric return true; 237306c3fb27SDimitry Andric } 237406c3fb27SDimitry Andric 2375*0fca6ea1SDimitry Andric /// Check if the mask is a DE-interleave mask of the given factor 2376*0fca6ea1SDimitry Andric /// \p Factor like: 2377*0fca6ea1SDimitry Andric /// <Index, Index+Factor, ..., Index+(NumElts-1)*Factor> 2378*0fca6ea1SDimitry Andric bool ShuffleVectorInst::isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, 2379*0fca6ea1SDimitry Andric unsigned Factor, 2380*0fca6ea1SDimitry Andric unsigned &Index) { 2381*0fca6ea1SDimitry Andric // Check all potential start indices from 0 to (Factor - 1). 2382*0fca6ea1SDimitry Andric for (unsigned Idx = 0; Idx < Factor; Idx++) { 2383*0fca6ea1SDimitry Andric unsigned I = 0; 2384*0fca6ea1SDimitry Andric 2385*0fca6ea1SDimitry Andric // Check that elements are in ascending order by Factor. Ignore undef 2386*0fca6ea1SDimitry Andric // elements. 2387*0fca6ea1SDimitry Andric for (; I < Mask.size(); I++) 2388*0fca6ea1SDimitry Andric if (Mask[I] >= 0 && static_cast<unsigned>(Mask[I]) != Idx + I * Factor) 2389*0fca6ea1SDimitry Andric break; 2390*0fca6ea1SDimitry Andric 2391*0fca6ea1SDimitry Andric if (I == Mask.size()) { 2392*0fca6ea1SDimitry Andric Index = Idx; 2393*0fca6ea1SDimitry Andric return true; 2394*0fca6ea1SDimitry Andric } 2395*0fca6ea1SDimitry Andric } 2396*0fca6ea1SDimitry Andric 2397*0fca6ea1SDimitry Andric return false; 2398*0fca6ea1SDimitry Andric } 2399*0fca6ea1SDimitry Andric 24005f757f3fSDimitry Andric /// Try to lower a vector shuffle as a bit rotation. 24015f757f3fSDimitry Andric /// 24025f757f3fSDimitry Andric /// Look for a repeated rotation pattern in each sub group. 24035f757f3fSDimitry Andric /// Returns an element-wise left bit rotation amount or -1 if failed. 24045f757f3fSDimitry Andric static int matchShuffleAsBitRotate(ArrayRef<int> Mask, int NumSubElts) { 24055f757f3fSDimitry Andric int NumElts = Mask.size(); 24065f757f3fSDimitry Andric assert((NumElts % NumSubElts) == 0 && "Illegal shuffle mask"); 24075f757f3fSDimitry Andric 24085f757f3fSDimitry Andric int RotateAmt = -1; 24095f757f3fSDimitry Andric for (int i = 0; i != NumElts; i += NumSubElts) { 24105f757f3fSDimitry Andric for (int j = 0; j != NumSubElts; ++j) { 24115f757f3fSDimitry Andric int M = Mask[i + j]; 24125f757f3fSDimitry Andric if (M < 0) 24135f757f3fSDimitry Andric continue; 24145f757f3fSDimitry Andric if (M < i || M >= i + NumSubElts) 24155f757f3fSDimitry Andric return -1; 24165f757f3fSDimitry Andric int Offset = (NumSubElts - (M - (i + j))) % NumSubElts; 24175f757f3fSDimitry Andric if (0 <= RotateAmt && Offset != RotateAmt) 24185f757f3fSDimitry Andric return -1; 24195f757f3fSDimitry Andric RotateAmt = Offset; 24205f757f3fSDimitry Andric } 24215f757f3fSDimitry Andric } 24225f757f3fSDimitry Andric return RotateAmt; 24235f757f3fSDimitry Andric } 24245f757f3fSDimitry Andric 24255f757f3fSDimitry Andric bool ShuffleVectorInst::isBitRotateMask( 24265f757f3fSDimitry Andric ArrayRef<int> Mask, unsigned EltSizeInBits, unsigned MinSubElts, 24275f757f3fSDimitry Andric unsigned MaxSubElts, unsigned &NumSubElts, unsigned &RotateAmt) { 24285f757f3fSDimitry Andric for (NumSubElts = MinSubElts; NumSubElts <= MaxSubElts; NumSubElts *= 2) { 24295f757f3fSDimitry Andric int EltRotateAmt = matchShuffleAsBitRotate(Mask, NumSubElts); 24305f757f3fSDimitry Andric if (EltRotateAmt < 0) 24315f757f3fSDimitry Andric continue; 24325f757f3fSDimitry Andric RotateAmt = EltRotateAmt * EltSizeInBits; 24335f757f3fSDimitry Andric return true; 24345f757f3fSDimitry Andric } 24355f757f3fSDimitry Andric 24365f757f3fSDimitry Andric return false; 24375f757f3fSDimitry Andric } 24385f757f3fSDimitry Andric 24390b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 24400b57cec5SDimitry Andric // InsertValueInst Class 24410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, 24440b57cec5SDimitry Andric const Twine &Name) { 24450b57cec5SDimitry Andric assert(getNumOperands() == 2 && "NumOperands not initialized?"); 24460b57cec5SDimitry Andric 24470b57cec5SDimitry Andric // There's no fundamental reason why we require at least one index 24480b57cec5SDimitry Andric // (other than weirdness with &*IdxBegin being invalid; see 24490b57cec5SDimitry Andric // getelementptr's init routine for example). But there's no 24500b57cec5SDimitry Andric // present need to support it. 24510b57cec5SDimitry Andric assert(!Idxs.empty() && "InsertValueInst must have at least one index"); 24520b57cec5SDimitry Andric 24530b57cec5SDimitry Andric assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == 24540b57cec5SDimitry Andric Val->getType() && "Inserted value must match indexed type!"); 24550b57cec5SDimitry Andric Op<0>() = Agg; 24560b57cec5SDimitry Andric Op<1>() = Val; 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andric Indices.append(Idxs.begin(), Idxs.end()); 24590b57cec5SDimitry Andric setName(Name); 24600b57cec5SDimitry Andric } 24610b57cec5SDimitry Andric 24620b57cec5SDimitry Andric InsertValueInst::InsertValueInst(const InsertValueInst &IVI) 24630b57cec5SDimitry Andric : Instruction(IVI.getType(), InsertValue, 24640b57cec5SDimitry Andric OperandTraits<InsertValueInst>::op_begin(this), 2), 24650b57cec5SDimitry Andric Indices(IVI.Indices) { 24660b57cec5SDimitry Andric Op<0>() = IVI.getOperand(0); 24670b57cec5SDimitry Andric Op<1>() = IVI.getOperand(1); 24680b57cec5SDimitry Andric SubclassOptionalData = IVI.SubclassOptionalData; 24690b57cec5SDimitry Andric } 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 24720b57cec5SDimitry Andric // ExtractValueInst Class 24730b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 24740b57cec5SDimitry Andric 24750b57cec5SDimitry Andric void ExtractValueInst::init(ArrayRef<unsigned> Idxs, const Twine &Name) { 24760b57cec5SDimitry Andric assert(getNumOperands() == 1 && "NumOperands not initialized?"); 24770b57cec5SDimitry Andric 24780b57cec5SDimitry Andric // There's no fundamental reason why we require at least one index. 24790b57cec5SDimitry Andric // But there's no present need to support it. 24800b57cec5SDimitry Andric assert(!Idxs.empty() && "ExtractValueInst must have at least one index"); 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric Indices.append(Idxs.begin(), Idxs.end()); 24830b57cec5SDimitry Andric setName(Name); 24840b57cec5SDimitry Andric } 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) 24870b57cec5SDimitry Andric : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)), 24880b57cec5SDimitry Andric Indices(EVI.Indices) { 24890b57cec5SDimitry Andric SubclassOptionalData = EVI.SubclassOptionalData; 24900b57cec5SDimitry Andric } 24910b57cec5SDimitry Andric 24920b57cec5SDimitry Andric // getIndexedType - Returns the type of the element that would be extracted 24930b57cec5SDimitry Andric // with an extractvalue instruction with the specified parameters. 24940b57cec5SDimitry Andric // 24950b57cec5SDimitry Andric // A null type is returned if the indices are invalid for the specified 24960b57cec5SDimitry Andric // pointer type. 24970b57cec5SDimitry Andric // 24980b57cec5SDimitry Andric Type *ExtractValueInst::getIndexedType(Type *Agg, 24990b57cec5SDimitry Andric ArrayRef<unsigned> Idxs) { 25000b57cec5SDimitry Andric for (unsigned Index : Idxs) { 25010b57cec5SDimitry Andric // We can't use CompositeType::indexValid(Index) here. 25020b57cec5SDimitry Andric // indexValid() always returns true for arrays because getelementptr allows 25030b57cec5SDimitry Andric // out-of-bounds indices. Since we don't allow those for extractvalue and 25040b57cec5SDimitry Andric // insertvalue we need to check array indexing manually. 25050b57cec5SDimitry Andric // Since the only other types we can index into are struct types it's just 25060b57cec5SDimitry Andric // as easy to check those manually as well. 25070b57cec5SDimitry Andric if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) { 25080b57cec5SDimitry Andric if (Index >= AT->getNumElements()) 25090b57cec5SDimitry Andric return nullptr; 25105ffd83dbSDimitry Andric Agg = AT->getElementType(); 25110b57cec5SDimitry Andric } else if (StructType *ST = dyn_cast<StructType>(Agg)) { 25120b57cec5SDimitry Andric if (Index >= ST->getNumElements()) 25130b57cec5SDimitry Andric return nullptr; 25145ffd83dbSDimitry Andric Agg = ST->getElementType(Index); 25150b57cec5SDimitry Andric } else { 25160b57cec5SDimitry Andric // Not a valid type to index into. 25170b57cec5SDimitry Andric return nullptr; 25180b57cec5SDimitry Andric } 25190b57cec5SDimitry Andric } 25200b57cec5SDimitry Andric return const_cast<Type*>(Agg); 25210b57cec5SDimitry Andric } 25220b57cec5SDimitry Andric 25230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25240b57cec5SDimitry Andric // UnaryOperator Class 25250b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25260b57cec5SDimitry Andric 2527*0fca6ea1SDimitry Andric UnaryOperator::UnaryOperator(UnaryOps iType, Value *S, Type *Ty, 2528*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) 25290b57cec5SDimitry Andric : UnaryInstruction(Ty, iType, S, InsertBefore) { 25300b57cec5SDimitry Andric Op<0>() = S; 25310b57cec5SDimitry Andric setName(Name); 25320b57cec5SDimitry Andric AssertOK(); 25330b57cec5SDimitry Andric } 25340b57cec5SDimitry Andric 2535*0fca6ea1SDimitry Andric UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S, const Twine &Name, 2536*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 25370b57cec5SDimitry Andric return new UnaryOperator(Op, S, S->getType(), Name, InsertBefore); 25380b57cec5SDimitry Andric } 25390b57cec5SDimitry Andric 25400b57cec5SDimitry Andric void UnaryOperator::AssertOK() { 25410b57cec5SDimitry Andric Value *LHS = getOperand(0); 25420b57cec5SDimitry Andric (void)LHS; // Silence warnings. 25430b57cec5SDimitry Andric #ifndef NDEBUG 25440b57cec5SDimitry Andric switch (getOpcode()) { 25450b57cec5SDimitry Andric case FNeg: 25460b57cec5SDimitry Andric assert(getType() == LHS->getType() && 25470b57cec5SDimitry Andric "Unary operation should return same type as operand!"); 25480b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() && 25490b57cec5SDimitry Andric "Tried to create a floating-point operation on a " 25500b57cec5SDimitry Andric "non-floating-point type!"); 25510b57cec5SDimitry Andric break; 25520b57cec5SDimitry Andric default: llvm_unreachable("Invalid opcode provided"); 25530b57cec5SDimitry Andric } 25540b57cec5SDimitry Andric #endif 25550b57cec5SDimitry Andric } 25560b57cec5SDimitry Andric 25570b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25580b57cec5SDimitry Andric // BinaryOperator Class 25590b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25600b57cec5SDimitry Andric 2561*0fca6ea1SDimitry Andric BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, 2562*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) 2563*0fca6ea1SDimitry Andric : Instruction(Ty, iType, OperandTraits<BinaryOperator>::op_begin(this), 2564*0fca6ea1SDimitry Andric OperandTraits<BinaryOperator>::operands(this), InsertBefore) { 25650b57cec5SDimitry Andric Op<0>() = S1; 25660b57cec5SDimitry Andric Op<1>() = S2; 25670b57cec5SDimitry Andric setName(Name); 25680b57cec5SDimitry Andric AssertOK(); 25690b57cec5SDimitry Andric } 25700b57cec5SDimitry Andric 25710b57cec5SDimitry Andric void BinaryOperator::AssertOK() { 25720b57cec5SDimitry Andric Value *LHS = getOperand(0), *RHS = getOperand(1); 25730b57cec5SDimitry Andric (void)LHS; (void)RHS; // Silence warnings. 25740b57cec5SDimitry Andric assert(LHS->getType() == RHS->getType() && 25750b57cec5SDimitry Andric "Binary operator operand types must match!"); 25760b57cec5SDimitry Andric #ifndef NDEBUG 25770b57cec5SDimitry Andric switch (getOpcode()) { 25780b57cec5SDimitry Andric case Add: case Sub: 25790b57cec5SDimitry Andric case Mul: 25800b57cec5SDimitry Andric assert(getType() == LHS->getType() && 25810b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 25820b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() && 25830b57cec5SDimitry Andric "Tried to create an integer operation on a non-integer type!"); 25840b57cec5SDimitry Andric break; 25850b57cec5SDimitry Andric case FAdd: case FSub: 25860b57cec5SDimitry Andric case FMul: 25870b57cec5SDimitry Andric assert(getType() == LHS->getType() && 25880b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 25890b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() && 25900b57cec5SDimitry Andric "Tried to create a floating-point operation on a " 25910b57cec5SDimitry Andric "non-floating-point type!"); 25920b57cec5SDimitry Andric break; 25930b57cec5SDimitry Andric case UDiv: 25940b57cec5SDimitry Andric case SDiv: 25950b57cec5SDimitry Andric assert(getType() == LHS->getType() && 25960b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 25970b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() && 25980b57cec5SDimitry Andric "Incorrect operand type (not integer) for S/UDIV"); 25990b57cec5SDimitry Andric break; 26000b57cec5SDimitry Andric case FDiv: 26010b57cec5SDimitry Andric assert(getType() == LHS->getType() && 26020b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 26030b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() && 26040b57cec5SDimitry Andric "Incorrect operand type (not floating point) for FDIV"); 26050b57cec5SDimitry Andric break; 26060b57cec5SDimitry Andric case URem: 26070b57cec5SDimitry Andric case SRem: 26080b57cec5SDimitry Andric assert(getType() == LHS->getType() && 26090b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 26100b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() && 26110b57cec5SDimitry Andric "Incorrect operand type (not integer) for S/UREM"); 26120b57cec5SDimitry Andric break; 26130b57cec5SDimitry Andric case FRem: 26140b57cec5SDimitry Andric assert(getType() == LHS->getType() && 26150b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!"); 26160b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() && 26170b57cec5SDimitry Andric "Incorrect operand type (not floating point) for FREM"); 26180b57cec5SDimitry Andric break; 26190b57cec5SDimitry Andric case Shl: 26200b57cec5SDimitry Andric case LShr: 26210b57cec5SDimitry Andric case AShr: 26220b57cec5SDimitry Andric assert(getType() == LHS->getType() && 26230b57cec5SDimitry Andric "Shift operation should return same type as operands!"); 26240b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() && 26250b57cec5SDimitry Andric "Tried to create a shift operation on a non-integral type!"); 26260b57cec5SDimitry Andric break; 26270b57cec5SDimitry Andric case And: case Or: 26280b57cec5SDimitry Andric case Xor: 26290b57cec5SDimitry Andric assert(getType() == LHS->getType() && 26300b57cec5SDimitry Andric "Logical operation should return same type as operands!"); 26310b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() && 26320b57cec5SDimitry Andric "Tried to create a logical operation on a non-integral type!"); 26330b57cec5SDimitry Andric break; 26340b57cec5SDimitry Andric default: llvm_unreachable("Invalid opcode provided"); 26350b57cec5SDimitry Andric } 26360b57cec5SDimitry Andric #endif 26370b57cec5SDimitry Andric } 26380b57cec5SDimitry Andric 26390b57cec5SDimitry Andric BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, 26400b57cec5SDimitry Andric const Twine &Name, 2641*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 26420b57cec5SDimitry Andric assert(S1->getType() == S2->getType() && 26430b57cec5SDimitry Andric "Cannot create binary operator with two operands of differing type!"); 26440b57cec5SDimitry Andric return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore); 26450b57cec5SDimitry Andric } 26460b57cec5SDimitry Andric 26470b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, 2648*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 264906c3fb27SDimitry Andric Value *Zero = ConstantInt::get(Op->getType(), 0); 2650*0fca6ea1SDimitry Andric return new BinaryOperator(Instruction::Sub, Zero, Op, Op->getType(), Name, 2651*0fca6ea1SDimitry Andric InsertBefore); 26520b57cec5SDimitry Andric } 26530b57cec5SDimitry Andric 26540b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, 2655*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 265606c3fb27SDimitry Andric Value *Zero = ConstantInt::get(Op->getType(), 0); 265706c3fb27SDimitry Andric return BinaryOperator::CreateNSWSub(Zero, Op, Name, InsertBefore); 26580b57cec5SDimitry Andric } 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, 2661*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 26620b57cec5SDimitry Andric Constant *C = Constant::getAllOnesValue(Op->getType()); 26630b57cec5SDimitry Andric return new BinaryOperator(Instruction::Xor, Op, C, 26640b57cec5SDimitry Andric Op->getType(), Name, InsertBefore); 26650b57cec5SDimitry Andric } 26660b57cec5SDimitry Andric 26670b57cec5SDimitry Andric // Exchange the two operands to this instruction. This instruction is safe to 26680b57cec5SDimitry Andric // use on any binary instruction and does not modify the semantics of the 26690b57cec5SDimitry Andric // instruction. If the instruction is order-dependent (SetLT f.e.), the opcode 26700b57cec5SDimitry Andric // is changed. 26710b57cec5SDimitry Andric bool BinaryOperator::swapOperands() { 26720b57cec5SDimitry Andric if (!isCommutative()) 26730b57cec5SDimitry Andric return true; // Can't commute operands 26740b57cec5SDimitry Andric Op<0>().swap(Op<1>()); 26750b57cec5SDimitry Andric return false; 26760b57cec5SDimitry Andric } 26770b57cec5SDimitry Andric 26780b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 26790b57cec5SDimitry Andric // FPMathOperator Class 26800b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andric float FPMathOperator::getFPAccuracy() const { 26830b57cec5SDimitry Andric const MDNode *MD = 26840b57cec5SDimitry Andric cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); 26850b57cec5SDimitry Andric if (!MD) 26860b57cec5SDimitry Andric return 0.0; 26870b57cec5SDimitry Andric ConstantFP *Accuracy = mdconst::extract<ConstantFP>(MD->getOperand(0)); 26880b57cec5SDimitry Andric return Accuracy->getValueAPF().convertToFloat(); 26890b57cec5SDimitry Andric } 26900b57cec5SDimitry Andric 26910b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 26920b57cec5SDimitry Andric // CastInst Class 26930b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 26940b57cec5SDimitry Andric 26950b57cec5SDimitry Andric // Just determine if this cast only deals with integral->integral conversion. 26960b57cec5SDimitry Andric bool CastInst::isIntegerCast() const { 26970b57cec5SDimitry Andric switch (getOpcode()) { 26980b57cec5SDimitry Andric default: return false; 26990b57cec5SDimitry Andric case Instruction::ZExt: 27000b57cec5SDimitry Andric case Instruction::SExt: 27010b57cec5SDimitry Andric case Instruction::Trunc: 27020b57cec5SDimitry Andric return true; 27030b57cec5SDimitry Andric case Instruction::BitCast: 27040b57cec5SDimitry Andric return getOperand(0)->getType()->isIntegerTy() && 27050b57cec5SDimitry Andric getType()->isIntegerTy(); 27060b57cec5SDimitry Andric } 27070b57cec5SDimitry Andric } 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andric /// This function determines if the CastInst does not require any bits to be 27100b57cec5SDimitry Andric /// changed in order to effect the cast. Essentially, it identifies cases where 27110b57cec5SDimitry Andric /// no code gen is necessary for the cast, hence the name no-op cast. For 27120b57cec5SDimitry Andric /// example, the following are all no-op casts: 27130b57cec5SDimitry Andric /// # bitcast i32* %x to i8* 27140b57cec5SDimitry Andric /// # bitcast <2 x i32> %x to <4 x i16> 27150b57cec5SDimitry Andric /// # ptrtoint i32* %x to i32 ; on 32-bit plaforms only 27160b57cec5SDimitry Andric /// Determine if the described cast is a no-op. 27170b57cec5SDimitry Andric bool CastInst::isNoopCast(Instruction::CastOps Opcode, 27180b57cec5SDimitry Andric Type *SrcTy, 27190b57cec5SDimitry Andric Type *DestTy, 27200b57cec5SDimitry Andric const DataLayout &DL) { 2721e8d8bef9SDimitry Andric assert(castIsValid(Opcode, SrcTy, DestTy) && "method precondition"); 27220b57cec5SDimitry Andric switch (Opcode) { 27230b57cec5SDimitry Andric default: llvm_unreachable("Invalid CastOp"); 27240b57cec5SDimitry Andric case Instruction::Trunc: 27250b57cec5SDimitry Andric case Instruction::ZExt: 27260b57cec5SDimitry Andric case Instruction::SExt: 27270b57cec5SDimitry Andric case Instruction::FPTrunc: 27280b57cec5SDimitry Andric case Instruction::FPExt: 27290b57cec5SDimitry Andric case Instruction::UIToFP: 27300b57cec5SDimitry Andric case Instruction::SIToFP: 27310b57cec5SDimitry Andric case Instruction::FPToUI: 27320b57cec5SDimitry Andric case Instruction::FPToSI: 27330b57cec5SDimitry Andric case Instruction::AddrSpaceCast: 27340b57cec5SDimitry Andric // TODO: Target informations may give a more accurate answer here. 27350b57cec5SDimitry Andric return false; 27360b57cec5SDimitry Andric case Instruction::BitCast: 27370b57cec5SDimitry Andric return true; // BitCast never modifies bits. 27380b57cec5SDimitry Andric case Instruction::PtrToInt: 27390b57cec5SDimitry Andric return DL.getIntPtrType(SrcTy)->getScalarSizeInBits() == 27400b57cec5SDimitry Andric DestTy->getScalarSizeInBits(); 27410b57cec5SDimitry Andric case Instruction::IntToPtr: 27420b57cec5SDimitry Andric return DL.getIntPtrType(DestTy)->getScalarSizeInBits() == 27430b57cec5SDimitry Andric SrcTy->getScalarSizeInBits(); 27440b57cec5SDimitry Andric } 27450b57cec5SDimitry Andric } 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andric bool CastInst::isNoopCast(const DataLayout &DL) const { 27480b57cec5SDimitry Andric return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), DL); 27490b57cec5SDimitry Andric } 27500b57cec5SDimitry Andric 27510b57cec5SDimitry Andric /// This function determines if a pair of casts can be eliminated and what 27520b57cec5SDimitry Andric /// opcode should be used in the elimination. This assumes that there are two 27530b57cec5SDimitry Andric /// instructions like this: 27540b57cec5SDimitry Andric /// * %F = firstOpcode SrcTy %x to MidTy 27550b57cec5SDimitry Andric /// * %S = secondOpcode MidTy %F to DstTy 27560b57cec5SDimitry Andric /// The function returns a resultOpcode so these two casts can be replaced with: 27570b57cec5SDimitry Andric /// * %Replacement = resultOpcode %SrcTy %x to DstTy 27580b57cec5SDimitry Andric /// If no such cast is permitted, the function returns 0. 27590b57cec5SDimitry Andric unsigned CastInst::isEliminableCastPair( 27600b57cec5SDimitry Andric Instruction::CastOps firstOp, Instruction::CastOps secondOp, 27610b57cec5SDimitry Andric Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, 27620b57cec5SDimitry Andric Type *DstIntPtrTy) { 27630b57cec5SDimitry Andric // Define the 144 possibilities for these two cast instructions. The values 27640b57cec5SDimitry Andric // in this matrix determine what to do in a given situation and select the 27650b57cec5SDimitry Andric // case in the switch below. The rows correspond to firstOp, the columns 27660b57cec5SDimitry Andric // correspond to secondOp. In looking at the table below, keep in mind 27670b57cec5SDimitry Andric // the following cast properties: 27680b57cec5SDimitry Andric // 27690b57cec5SDimitry Andric // Size Compare Source Destination 27700b57cec5SDimitry Andric // Operator Src ? Size Type Sign Type Sign 27710b57cec5SDimitry Andric // -------- ------------ ------------------- --------------------- 27720b57cec5SDimitry Andric // TRUNC > Integer Any Integral Any 27730b57cec5SDimitry Andric // ZEXT < Integral Unsigned Integer Any 27740b57cec5SDimitry Andric // SEXT < Integral Signed Integer Any 27750b57cec5SDimitry Andric // FPTOUI n/a FloatPt n/a Integral Unsigned 27760b57cec5SDimitry Andric // FPTOSI n/a FloatPt n/a Integral Signed 27770b57cec5SDimitry Andric // UITOFP n/a Integral Unsigned FloatPt n/a 27780b57cec5SDimitry Andric // SITOFP n/a Integral Signed FloatPt n/a 27790b57cec5SDimitry Andric // FPTRUNC > FloatPt n/a FloatPt n/a 27800b57cec5SDimitry Andric // FPEXT < FloatPt n/a FloatPt n/a 27810b57cec5SDimitry Andric // PTRTOINT n/a Pointer n/a Integral Unsigned 27820b57cec5SDimitry Andric // INTTOPTR n/a Integral Unsigned Pointer n/a 27830b57cec5SDimitry Andric // BITCAST = FirstClass n/a FirstClass n/a 27840b57cec5SDimitry Andric // ADDRSPCST n/a Pointer n/a Pointer n/a 27850b57cec5SDimitry Andric // 27860b57cec5SDimitry Andric // NOTE: some transforms are safe, but we consider them to be non-profitable. 27870b57cec5SDimitry Andric // For example, we could merge "fptoui double to i32" + "zext i32 to i64", 27880b57cec5SDimitry Andric // into "fptoui double to i64", but this loses information about the range 27890b57cec5SDimitry Andric // of the produced value (we no longer know the top-part is all zeros). 27900b57cec5SDimitry Andric // Further this conversion is often much more expensive for typical hardware, 27910b57cec5SDimitry Andric // and causes issues when building libgcc. We disallow fptosi+sext for the 27920b57cec5SDimitry Andric // same reason. 27930b57cec5SDimitry Andric const unsigned numCastOps = 27940b57cec5SDimitry Andric Instruction::CastOpsEnd - Instruction::CastOpsBegin; 27950b57cec5SDimitry Andric static const uint8_t CastResults[numCastOps][numCastOps] = { 27960b57cec5SDimitry Andric // T F F U S F F P I B A -+ 27970b57cec5SDimitry Andric // R Z S P P I I T P 2 N T S | 27980b57cec5SDimitry Andric // U E E 2 2 2 2 R E I T C C +- secondOp 27990b57cec5SDimitry Andric // N X X U S F F N X N 2 V V | 28000b57cec5SDimitry Andric // C T T I I P P C T T P T T -+ 28010b57cec5SDimitry Andric { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ 28020b57cec5SDimitry Andric { 8, 1, 9,99,99, 2,17,99,99,99, 2, 3, 0}, // ZExt | 28030b57cec5SDimitry Andric { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | 28040b57cec5SDimitry Andric { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | 28050b57cec5SDimitry Andric { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | 28060b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp 28070b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | 28080b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // FPTrunc | 28090b57cec5SDimitry Andric { 99,99,99, 2, 2,99,99, 8, 2,99,99, 4, 0}, // FPExt | 28100b57cec5SDimitry Andric { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | 28110b57cec5SDimitry Andric { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | 2812*0fca6ea1SDimitry Andric { 5, 5, 5, 0, 0, 5, 5, 0, 0,16, 5, 1,14}, // BitCast | 28130b57cec5SDimitry Andric { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ 28140b57cec5SDimitry Andric }; 28150b57cec5SDimitry Andric 28160b57cec5SDimitry Andric // TODO: This logic could be encoded into the table above and handled in the 28170b57cec5SDimitry Andric // switch below. 28180b57cec5SDimitry Andric // If either of the casts are a bitcast from scalar to vector, disallow the 28190b57cec5SDimitry Andric // merging. However, any pair of bitcasts are allowed. 28200b57cec5SDimitry Andric bool IsFirstBitcast = (firstOp == Instruction::BitCast); 28210b57cec5SDimitry Andric bool IsSecondBitcast = (secondOp == Instruction::BitCast); 28220b57cec5SDimitry Andric bool AreBothBitcasts = IsFirstBitcast && IsSecondBitcast; 28230b57cec5SDimitry Andric 28240b57cec5SDimitry Andric // Check if any of the casts convert scalars <-> vectors. 28250b57cec5SDimitry Andric if ((IsFirstBitcast && isa<VectorType>(SrcTy) != isa<VectorType>(MidTy)) || 28260b57cec5SDimitry Andric (IsSecondBitcast && isa<VectorType>(MidTy) != isa<VectorType>(DstTy))) 28270b57cec5SDimitry Andric if (!AreBothBitcasts) 28280b57cec5SDimitry Andric return 0; 28290b57cec5SDimitry Andric 28300b57cec5SDimitry Andric int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin] 28310b57cec5SDimitry Andric [secondOp-Instruction::CastOpsBegin]; 28320b57cec5SDimitry Andric switch (ElimCase) { 28330b57cec5SDimitry Andric case 0: 28340b57cec5SDimitry Andric // Categorically disallowed. 28350b57cec5SDimitry Andric return 0; 28360b57cec5SDimitry Andric case 1: 28370b57cec5SDimitry Andric // Allowed, use first cast's opcode. 28380b57cec5SDimitry Andric return firstOp; 28390b57cec5SDimitry Andric case 2: 28400b57cec5SDimitry Andric // Allowed, use second cast's opcode. 28410b57cec5SDimitry Andric return secondOp; 28420b57cec5SDimitry Andric case 3: 28430b57cec5SDimitry Andric // No-op cast in second op implies firstOp as long as the DestTy 28440b57cec5SDimitry Andric // is integer and we are not converting between a vector and a 28450b57cec5SDimitry Andric // non-vector type. 28460b57cec5SDimitry Andric if (!SrcTy->isVectorTy() && DstTy->isIntegerTy()) 28470b57cec5SDimitry Andric return firstOp; 28480b57cec5SDimitry Andric return 0; 28490b57cec5SDimitry Andric case 4: 28500b57cec5SDimitry Andric // No-op cast in second op implies firstOp as long as the DestTy 28517a6dacacSDimitry Andric // matches MidTy. 28527a6dacacSDimitry Andric if (DstTy == MidTy) 28530b57cec5SDimitry Andric return firstOp; 28540b57cec5SDimitry Andric return 0; 28550b57cec5SDimitry Andric case 5: 28560b57cec5SDimitry Andric // No-op cast in first op implies secondOp as long as the SrcTy 28570b57cec5SDimitry Andric // is an integer. 28580b57cec5SDimitry Andric if (SrcTy->isIntegerTy()) 28590b57cec5SDimitry Andric return secondOp; 28600b57cec5SDimitry Andric return 0; 28610b57cec5SDimitry Andric case 7: { 2862fe6060f1SDimitry Andric // Disable inttoptr/ptrtoint optimization if enabled. 2863fe6060f1SDimitry Andric if (DisableI2pP2iOpt) 2864fe6060f1SDimitry Andric return 0; 2865fe6060f1SDimitry Andric 28660b57cec5SDimitry Andric // Cannot simplify if address spaces are different! 28670b57cec5SDimitry Andric if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) 28680b57cec5SDimitry Andric return 0; 28690b57cec5SDimitry Andric 28700b57cec5SDimitry Andric unsigned MidSize = MidTy->getScalarSizeInBits(); 28710b57cec5SDimitry Andric // We can still fold this without knowing the actual sizes as long we 28720b57cec5SDimitry Andric // know that the intermediate pointer is the largest possible 28730b57cec5SDimitry Andric // pointer size. 28740b57cec5SDimitry Andric // FIXME: Is this always true? 28750b57cec5SDimitry Andric if (MidSize == 64) 28760b57cec5SDimitry Andric return Instruction::BitCast; 28770b57cec5SDimitry Andric 28780b57cec5SDimitry Andric // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size. 28790b57cec5SDimitry Andric if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy) 28800b57cec5SDimitry Andric return 0; 28810b57cec5SDimitry Andric unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits(); 28820b57cec5SDimitry Andric if (MidSize >= PtrSize) 28830b57cec5SDimitry Andric return Instruction::BitCast; 28840b57cec5SDimitry Andric return 0; 28850b57cec5SDimitry Andric } 28860b57cec5SDimitry Andric case 8: { 288781ad6265SDimitry Andric // ext, trunc -> bitcast, if the SrcTy and DstTy are the same 28880b57cec5SDimitry Andric // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy) 28890b57cec5SDimitry Andric // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy) 28900b57cec5SDimitry Andric unsigned SrcSize = SrcTy->getScalarSizeInBits(); 28910b57cec5SDimitry Andric unsigned DstSize = DstTy->getScalarSizeInBits(); 289281ad6265SDimitry Andric if (SrcTy == DstTy) 28930b57cec5SDimitry Andric return Instruction::BitCast; 289481ad6265SDimitry Andric if (SrcSize < DstSize) 28950b57cec5SDimitry Andric return firstOp; 289681ad6265SDimitry Andric if (SrcSize > DstSize) 28970b57cec5SDimitry Andric return secondOp; 289881ad6265SDimitry Andric return 0; 28990b57cec5SDimitry Andric } 29000b57cec5SDimitry Andric case 9: 29010b57cec5SDimitry Andric // zext, sext -> zext, because sext can't sign extend after zext 29020b57cec5SDimitry Andric return Instruction::ZExt; 29030b57cec5SDimitry Andric case 11: { 29040b57cec5SDimitry Andric // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize 29050b57cec5SDimitry Andric if (!MidIntPtrTy) 29060b57cec5SDimitry Andric return 0; 29070b57cec5SDimitry Andric unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits(); 29080b57cec5SDimitry Andric unsigned SrcSize = SrcTy->getScalarSizeInBits(); 29090b57cec5SDimitry Andric unsigned DstSize = DstTy->getScalarSizeInBits(); 29100b57cec5SDimitry Andric if (SrcSize <= PtrSize && SrcSize == DstSize) 29110b57cec5SDimitry Andric return Instruction::BitCast; 29120b57cec5SDimitry Andric return 0; 29130b57cec5SDimitry Andric } 29140b57cec5SDimitry Andric case 12: 29150b57cec5SDimitry Andric // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS 29160b57cec5SDimitry Andric // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS 29170b57cec5SDimitry Andric if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) 29180b57cec5SDimitry Andric return Instruction::AddrSpaceCast; 29190b57cec5SDimitry Andric return Instruction::BitCast; 29200b57cec5SDimitry Andric case 13: 29210b57cec5SDimitry Andric // FIXME: this state can be merged with (1), but the following assert 29220b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic 29230b57cec5SDimitry Andric // change of bitcast. 29240b57cec5SDimitry Andric assert( 29250b57cec5SDimitry Andric SrcTy->isPtrOrPtrVectorTy() && 29260b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() && 29270b57cec5SDimitry Andric DstTy->isPtrOrPtrVectorTy() && 29280b57cec5SDimitry Andric SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() && 29290b57cec5SDimitry Andric MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && 29300b57cec5SDimitry Andric "Illegal addrspacecast, bitcast sequence!"); 29310b57cec5SDimitry Andric // Allowed, use first cast's opcode 29320b57cec5SDimitry Andric return firstOp; 293306c3fb27SDimitry Andric case 14: 293406c3fb27SDimitry Andric // bitcast, addrspacecast -> addrspacecast 29350b57cec5SDimitry Andric return Instruction::AddrSpaceCast; 29360b57cec5SDimitry Andric case 15: 29370b57cec5SDimitry Andric // FIXME: this state can be merged with (1), but the following assert 29380b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic 29390b57cec5SDimitry Andric // change of bitcast. 29400b57cec5SDimitry Andric assert( 29410b57cec5SDimitry Andric SrcTy->isIntOrIntVectorTy() && 29420b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() && 29430b57cec5SDimitry Andric DstTy->isPtrOrPtrVectorTy() && 29440b57cec5SDimitry Andric MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && 29450b57cec5SDimitry Andric "Illegal inttoptr, bitcast sequence!"); 29460b57cec5SDimitry Andric // Allowed, use first cast's opcode 29470b57cec5SDimitry Andric return firstOp; 29480b57cec5SDimitry Andric case 16: 29490b57cec5SDimitry Andric // FIXME: this state can be merged with (2), but the following assert 29500b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic 29510b57cec5SDimitry Andric // change of bitcast. 29520b57cec5SDimitry Andric assert( 29530b57cec5SDimitry Andric SrcTy->isPtrOrPtrVectorTy() && 29540b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() && 29550b57cec5SDimitry Andric DstTy->isIntOrIntVectorTy() && 29560b57cec5SDimitry Andric SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && 29570b57cec5SDimitry Andric "Illegal bitcast, ptrtoint sequence!"); 29580b57cec5SDimitry Andric // Allowed, use second cast's opcode 29590b57cec5SDimitry Andric return secondOp; 29600b57cec5SDimitry Andric case 17: 29610b57cec5SDimitry Andric // (sitofp (zext x)) -> (uitofp x) 29620b57cec5SDimitry Andric return Instruction::UIToFP; 29630b57cec5SDimitry Andric case 99: 29640b57cec5SDimitry Andric // Cast combination can't happen (error in input). This is for all cases 29650b57cec5SDimitry Andric // where the MidTy is not the same for the two cast instructions. 29660b57cec5SDimitry Andric llvm_unreachable("Invalid Cast Combination"); 29670b57cec5SDimitry Andric default: 29680b57cec5SDimitry Andric llvm_unreachable("Error in CastResults table!!!"); 29690b57cec5SDimitry Andric } 29700b57cec5SDimitry Andric } 29710b57cec5SDimitry Andric 29720b57cec5SDimitry Andric CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, 2973*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) { 29740b57cec5SDimitry Andric assert(castIsValid(op, S, Ty) && "Invalid cast!"); 29750b57cec5SDimitry Andric // Construct and return the appropriate CastInst subclass 29760b57cec5SDimitry Andric switch (op) { 29770b57cec5SDimitry Andric case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); 29780b57cec5SDimitry Andric case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); 29790b57cec5SDimitry Andric case SExt: return new SExtInst (S, Ty, Name, InsertBefore); 29800b57cec5SDimitry Andric case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); 29810b57cec5SDimitry Andric case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); 29820b57cec5SDimitry Andric case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); 29830b57cec5SDimitry Andric case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); 29840b57cec5SDimitry Andric case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); 29850b57cec5SDimitry Andric case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); 29860b57cec5SDimitry Andric case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); 29870b57cec5SDimitry Andric case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); 2988*0fca6ea1SDimitry Andric case BitCast: 2989*0fca6ea1SDimitry Andric return new BitCastInst(S, Ty, Name, InsertBefore); 2990*0fca6ea1SDimitry Andric case AddrSpaceCast: 2991*0fca6ea1SDimitry Andric return new AddrSpaceCastInst(S, Ty, Name, InsertBefore); 2992*0fca6ea1SDimitry Andric default: 2993*0fca6ea1SDimitry Andric llvm_unreachable("Invalid opcode provided"); 29940b57cec5SDimitry Andric } 29950b57cec5SDimitry Andric } 29960b57cec5SDimitry Andric 2997*0fca6ea1SDimitry Andric CastInst *CastInst::CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name, 2998*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 29990b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) 30000b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); 30010b57cec5SDimitry Andric return Create(Instruction::ZExt, S, Ty, Name, InsertBefore); 30020b57cec5SDimitry Andric } 30030b57cec5SDimitry Andric 3004*0fca6ea1SDimitry Andric CastInst *CastInst::CreateSExtOrBitCast(Value *S, Type *Ty, const Twine &Name, 3005*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30060b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) 30070b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); 30080b57cec5SDimitry Andric return Create(Instruction::SExt, S, Ty, Name, InsertBefore); 30090b57cec5SDimitry Andric } 30100b57cec5SDimitry Andric 3011*0fca6ea1SDimitry Andric CastInst *CastInst::CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name, 3012*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30130b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) 30140b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); 30150b57cec5SDimitry Andric return Create(Instruction::Trunc, S, Ty, Name, InsertBefore); 30160b57cec5SDimitry Andric } 30170b57cec5SDimitry Andric 30180b57cec5SDimitry Andric /// Create a BitCast or a PtrToInt cast instruction 3019*0fca6ea1SDimitry Andric CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, const Twine &Name, 3020*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30210b57cec5SDimitry Andric assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); 30220b57cec5SDimitry Andric assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && 30230b57cec5SDimitry Andric "Invalid cast"); 30240b57cec5SDimitry Andric assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast"); 30250b57cec5SDimitry Andric assert((!Ty->isVectorTy() || 3026e8d8bef9SDimitry Andric cast<VectorType>(Ty)->getElementCount() == 3027e8d8bef9SDimitry Andric cast<VectorType>(S->getType())->getElementCount()) && 30280b57cec5SDimitry Andric "Invalid cast"); 30290b57cec5SDimitry Andric 30300b57cec5SDimitry Andric if (Ty->isIntOrIntVectorTy()) 30310b57cec5SDimitry Andric return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); 30320b57cec5SDimitry Andric 30330b57cec5SDimitry Andric return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore); 30340b57cec5SDimitry Andric } 30350b57cec5SDimitry Andric 30360b57cec5SDimitry Andric CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( 3037*0fca6ea1SDimitry Andric Value *S, Type *Ty, const Twine &Name, InsertPosition InsertBefore) { 30380b57cec5SDimitry Andric assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); 30390b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); 30400b57cec5SDimitry Andric 30410b57cec5SDimitry Andric if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) 30420b57cec5SDimitry Andric return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); 30430b57cec5SDimitry Andric 30440b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); 30450b57cec5SDimitry Andric } 30460b57cec5SDimitry Andric 30470b57cec5SDimitry Andric CastInst *CastInst::CreateBitOrPointerCast(Value *S, Type *Ty, 30480b57cec5SDimitry Andric const Twine &Name, 3049*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30500b57cec5SDimitry Andric if (S->getType()->isPointerTy() && Ty->isIntegerTy()) 30510b57cec5SDimitry Andric return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); 30520b57cec5SDimitry Andric if (S->getType()->isIntegerTy() && Ty->isPointerTy()) 30530b57cec5SDimitry Andric return Create(Instruction::IntToPtr, S, Ty, Name, InsertBefore); 30540b57cec5SDimitry Andric 30550b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); 30560b57cec5SDimitry Andric } 30570b57cec5SDimitry Andric 3058*0fca6ea1SDimitry Andric CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned, 3059*0fca6ea1SDimitry Andric const Twine &Name, 3060*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30610b57cec5SDimitry Andric assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && 30620b57cec5SDimitry Andric "Invalid integer cast"); 30630b57cec5SDimitry Andric unsigned SrcBits = C->getType()->getScalarSizeInBits(); 30640b57cec5SDimitry Andric unsigned DstBits = Ty->getScalarSizeInBits(); 30650b57cec5SDimitry Andric Instruction::CastOps opcode = 30660b57cec5SDimitry Andric (SrcBits == DstBits ? Instruction::BitCast : 30670b57cec5SDimitry Andric (SrcBits > DstBits ? Instruction::Trunc : 30680b57cec5SDimitry Andric (isSigned ? Instruction::SExt : Instruction::ZExt))); 30690b57cec5SDimitry Andric return Create(opcode, C, Ty, Name, InsertBefore); 30700b57cec5SDimitry Andric } 30710b57cec5SDimitry Andric 3072*0fca6ea1SDimitry Andric CastInst *CastInst::CreateFPCast(Value *C, Type *Ty, const Twine &Name, 3073*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 30740b57cec5SDimitry Andric assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && 30750b57cec5SDimitry Andric "Invalid cast"); 30760b57cec5SDimitry Andric unsigned SrcBits = C->getType()->getScalarSizeInBits(); 30770b57cec5SDimitry Andric unsigned DstBits = Ty->getScalarSizeInBits(); 3078*0fca6ea1SDimitry Andric assert((C->getType() == Ty || SrcBits != DstBits) && "Invalid cast"); 30790b57cec5SDimitry Andric Instruction::CastOps opcode = 30800b57cec5SDimitry Andric (SrcBits == DstBits ? Instruction::BitCast : 30810b57cec5SDimitry Andric (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); 30820b57cec5SDimitry Andric return Create(opcode, C, Ty, Name, InsertBefore); 30830b57cec5SDimitry Andric } 30840b57cec5SDimitry Andric 30850b57cec5SDimitry Andric bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) { 30860b57cec5SDimitry Andric if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType()) 30870b57cec5SDimitry Andric return false; 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric if (SrcTy == DestTy) 30900b57cec5SDimitry Andric return true; 30910b57cec5SDimitry Andric 30920b57cec5SDimitry Andric if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) { 30930b57cec5SDimitry Andric if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) { 30948bcb0991SDimitry Andric if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) { 30950b57cec5SDimitry Andric // An element by element cast. Valid if casting the elements is valid. 30960b57cec5SDimitry Andric SrcTy = SrcVecTy->getElementType(); 30970b57cec5SDimitry Andric DestTy = DestVecTy->getElementType(); 30980b57cec5SDimitry Andric } 30990b57cec5SDimitry Andric } 31000b57cec5SDimitry Andric } 31010b57cec5SDimitry Andric 31020b57cec5SDimitry Andric if (PointerType *DestPtrTy = dyn_cast<PointerType>(DestTy)) { 31030b57cec5SDimitry Andric if (PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy)) { 31040b57cec5SDimitry Andric return SrcPtrTy->getAddressSpace() == DestPtrTy->getAddressSpace(); 31050b57cec5SDimitry Andric } 31060b57cec5SDimitry Andric } 31070b57cec5SDimitry Andric 31088bcb0991SDimitry Andric TypeSize SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr 31098bcb0991SDimitry Andric TypeSize DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr 31100b57cec5SDimitry Andric 31110b57cec5SDimitry Andric // Could still have vectors of pointers if the number of elements doesn't 31120b57cec5SDimitry Andric // match 3113bdd1243dSDimitry Andric if (SrcBits.getKnownMinValue() == 0 || DestBits.getKnownMinValue() == 0) 31140b57cec5SDimitry Andric return false; 31150b57cec5SDimitry Andric 31160b57cec5SDimitry Andric if (SrcBits != DestBits) 31170b57cec5SDimitry Andric return false; 31180b57cec5SDimitry Andric 31190b57cec5SDimitry Andric if (DestTy->isX86_MMXTy() || SrcTy->isX86_MMXTy()) 31200b57cec5SDimitry Andric return false; 31210b57cec5SDimitry Andric 31220b57cec5SDimitry Andric return true; 31230b57cec5SDimitry Andric } 31240b57cec5SDimitry Andric 31250b57cec5SDimitry Andric bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, 31260b57cec5SDimitry Andric const DataLayout &DL) { 31270b57cec5SDimitry Andric // ptrtoint and inttoptr are not allowed on non-integral pointers 31280b57cec5SDimitry Andric if (auto *PtrTy = dyn_cast<PointerType>(SrcTy)) 31290b57cec5SDimitry Andric if (auto *IntTy = dyn_cast<IntegerType>(DestTy)) 31300b57cec5SDimitry Andric return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) && 31310b57cec5SDimitry Andric !DL.isNonIntegralPointerType(PtrTy)); 31320b57cec5SDimitry Andric if (auto *PtrTy = dyn_cast<PointerType>(DestTy)) 31330b57cec5SDimitry Andric if (auto *IntTy = dyn_cast<IntegerType>(SrcTy)) 31340b57cec5SDimitry Andric return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) && 31350b57cec5SDimitry Andric !DL.isNonIntegralPointerType(PtrTy)); 31360b57cec5SDimitry Andric 31370b57cec5SDimitry Andric return isBitCastable(SrcTy, DestTy); 31380b57cec5SDimitry Andric } 31390b57cec5SDimitry Andric 31400b57cec5SDimitry Andric // Provide a way to get a "cast" where the cast opcode is inferred from the 31410b57cec5SDimitry Andric // types and size of the operand. This, basically, is a parallel of the 31420b57cec5SDimitry Andric // logic in the castIsValid function below. This axiom should hold: 31430b57cec5SDimitry Andric // castIsValid( getCastOpcode(Val, Ty), Val, Ty) 31440b57cec5SDimitry Andric // should not assert in castIsValid. In other words, this produces a "correct" 31450b57cec5SDimitry Andric // casting opcode for the arguments passed to it. 31460b57cec5SDimitry Andric Instruction::CastOps 31470b57cec5SDimitry Andric CastInst::getCastOpcode( 31480b57cec5SDimitry Andric const Value *Src, bool SrcIsSigned, Type *DestTy, bool DestIsSigned) { 31490b57cec5SDimitry Andric Type *SrcTy = Src->getType(); 31500b57cec5SDimitry Andric 31510b57cec5SDimitry Andric assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() && 31520b57cec5SDimitry Andric "Only first class types are castable!"); 31530b57cec5SDimitry Andric 31540b57cec5SDimitry Andric if (SrcTy == DestTy) 31550b57cec5SDimitry Andric return BitCast; 31560b57cec5SDimitry Andric 31570b57cec5SDimitry Andric // FIXME: Check address space sizes here 31580b57cec5SDimitry Andric if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) 31590b57cec5SDimitry Andric if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) 3160e8d8bef9SDimitry Andric if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) { 31610b57cec5SDimitry Andric // An element by element cast. Find the appropriate opcode based on the 31620b57cec5SDimitry Andric // element types. 31630b57cec5SDimitry Andric SrcTy = SrcVecTy->getElementType(); 31640b57cec5SDimitry Andric DestTy = DestVecTy->getElementType(); 31650b57cec5SDimitry Andric } 31660b57cec5SDimitry Andric 31670b57cec5SDimitry Andric // Get the bit sizes, we'll need these 31680b57cec5SDimitry Andric unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr 31690b57cec5SDimitry Andric unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr 31700b57cec5SDimitry Andric 31710b57cec5SDimitry Andric // Run through the possibilities ... 31720b57cec5SDimitry Andric if (DestTy->isIntegerTy()) { // Casting to integral 31730b57cec5SDimitry Andric if (SrcTy->isIntegerTy()) { // Casting from integral 31740b57cec5SDimitry Andric if (DestBits < SrcBits) 31750b57cec5SDimitry Andric return Trunc; // int -> smaller int 31760b57cec5SDimitry Andric else if (DestBits > SrcBits) { // its an extension 31770b57cec5SDimitry Andric if (SrcIsSigned) 31780b57cec5SDimitry Andric return SExt; // signed -> SEXT 31790b57cec5SDimitry Andric else 31800b57cec5SDimitry Andric return ZExt; // unsigned -> ZEXT 31810b57cec5SDimitry Andric } else { 31820b57cec5SDimitry Andric return BitCast; // Same size, No-op cast 31830b57cec5SDimitry Andric } 31840b57cec5SDimitry Andric } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt 31850b57cec5SDimitry Andric if (DestIsSigned) 31860b57cec5SDimitry Andric return FPToSI; // FP -> sint 31870b57cec5SDimitry Andric else 31880b57cec5SDimitry Andric return FPToUI; // FP -> uint 31890b57cec5SDimitry Andric } else if (SrcTy->isVectorTy()) { 31900b57cec5SDimitry Andric assert(DestBits == SrcBits && 31910b57cec5SDimitry Andric "Casting vector to integer of different width"); 31920b57cec5SDimitry Andric return BitCast; // Same size, no-op cast 31930b57cec5SDimitry Andric } else { 31940b57cec5SDimitry Andric assert(SrcTy->isPointerTy() && 31950b57cec5SDimitry Andric "Casting from a value that is not first-class type"); 31960b57cec5SDimitry Andric return PtrToInt; // ptr -> int 31970b57cec5SDimitry Andric } 31980b57cec5SDimitry Andric } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt 31990b57cec5SDimitry Andric if (SrcTy->isIntegerTy()) { // Casting from integral 32000b57cec5SDimitry Andric if (SrcIsSigned) 32010b57cec5SDimitry Andric return SIToFP; // sint -> FP 32020b57cec5SDimitry Andric else 32030b57cec5SDimitry Andric return UIToFP; // uint -> FP 32040b57cec5SDimitry Andric } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt 32050b57cec5SDimitry Andric if (DestBits < SrcBits) { 32060b57cec5SDimitry Andric return FPTrunc; // FP -> smaller FP 32070b57cec5SDimitry Andric } else if (DestBits > SrcBits) { 32080b57cec5SDimitry Andric return FPExt; // FP -> larger FP 32090b57cec5SDimitry Andric } else { 32100b57cec5SDimitry Andric return BitCast; // same size, no-op cast 32110b57cec5SDimitry Andric } 32120b57cec5SDimitry Andric } else if (SrcTy->isVectorTy()) { 32130b57cec5SDimitry Andric assert(DestBits == SrcBits && 32140b57cec5SDimitry Andric "Casting vector to floating point of different width"); 32150b57cec5SDimitry Andric return BitCast; // same size, no-op cast 32160b57cec5SDimitry Andric } 32170b57cec5SDimitry Andric llvm_unreachable("Casting pointer or non-first class to float"); 32180b57cec5SDimitry Andric } else if (DestTy->isVectorTy()) { 32190b57cec5SDimitry Andric assert(DestBits == SrcBits && 32200b57cec5SDimitry Andric "Illegal cast to vector (wrong type or size)"); 32210b57cec5SDimitry Andric return BitCast; 32220b57cec5SDimitry Andric } else if (DestTy->isPointerTy()) { 32230b57cec5SDimitry Andric if (SrcTy->isPointerTy()) { 32240b57cec5SDimitry Andric if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace()) 32250b57cec5SDimitry Andric return AddrSpaceCast; 32260b57cec5SDimitry Andric return BitCast; // ptr -> ptr 32270b57cec5SDimitry Andric } else if (SrcTy->isIntegerTy()) { 32280b57cec5SDimitry Andric return IntToPtr; // int -> ptr 32290b57cec5SDimitry Andric } 32300b57cec5SDimitry Andric llvm_unreachable("Casting pointer to other than pointer or int"); 32310b57cec5SDimitry Andric } else if (DestTy->isX86_MMXTy()) { 32320b57cec5SDimitry Andric if (SrcTy->isVectorTy()) { 32330b57cec5SDimitry Andric assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); 32340b57cec5SDimitry Andric return BitCast; // 64-bit vector to MMX 32350b57cec5SDimitry Andric } 32360b57cec5SDimitry Andric llvm_unreachable("Illegal cast to X86_MMX"); 32370b57cec5SDimitry Andric } 32380b57cec5SDimitry Andric llvm_unreachable("Casting to type that is not first-class"); 32390b57cec5SDimitry Andric } 32400b57cec5SDimitry Andric 32410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 32420b57cec5SDimitry Andric // CastInst SubClass Constructors 32430b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 32440b57cec5SDimitry Andric 32450b57cec5SDimitry Andric /// Check that the construction parameters for a CastInst are correct. This 32460b57cec5SDimitry Andric /// could be broken out into the separate constructors but it is useful to have 32470b57cec5SDimitry Andric /// it in one place and to eliminate the redundant code for getting the sizes 32480b57cec5SDimitry Andric /// of the types involved. 32490b57cec5SDimitry Andric bool 3250e8d8bef9SDimitry Andric CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) { 32510b57cec5SDimitry Andric if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() || 32520b57cec5SDimitry Andric SrcTy->isAggregateType() || DstTy->isAggregateType()) 32530b57cec5SDimitry Andric return false; 32540b57cec5SDimitry Andric 32555ffd83dbSDimitry Andric // Get the size of the types in bits, and whether we are dealing 32565ffd83dbSDimitry Andric // with vector types, we'll need this later. 32575ffd83dbSDimitry Andric bool SrcIsVec = isa<VectorType>(SrcTy); 32585ffd83dbSDimitry Andric bool DstIsVec = isa<VectorType>(DstTy); 32595ffd83dbSDimitry Andric unsigned SrcScalarBitSize = SrcTy->getScalarSizeInBits(); 32605ffd83dbSDimitry Andric unsigned DstScalarBitSize = DstTy->getScalarSizeInBits(); 32610b57cec5SDimitry Andric 32620b57cec5SDimitry Andric // If these are vector types, get the lengths of the vectors (using zero for 32630b57cec5SDimitry Andric // scalar types means that checking that vector lengths match also checks that 32640b57cec5SDimitry Andric // scalars are not being converted to vectors or vectors to scalars). 32655ffd83dbSDimitry Andric ElementCount SrcEC = SrcIsVec ? cast<VectorType>(SrcTy)->getElementCount() 3266e8d8bef9SDimitry Andric : ElementCount::getFixed(0); 32675ffd83dbSDimitry Andric ElementCount DstEC = DstIsVec ? cast<VectorType>(DstTy)->getElementCount() 3268e8d8bef9SDimitry Andric : ElementCount::getFixed(0); 32690b57cec5SDimitry Andric 32700b57cec5SDimitry Andric // Switch on the opcode provided 32710b57cec5SDimitry Andric switch (op) { 32720b57cec5SDimitry Andric default: return false; // This is an input error 32730b57cec5SDimitry Andric case Instruction::Trunc: 32740b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && 32755ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize > DstScalarBitSize; 32760b57cec5SDimitry Andric case Instruction::ZExt: 32770b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && 32785ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize; 32790b57cec5SDimitry Andric case Instruction::SExt: 32800b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && 32815ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize; 32820b57cec5SDimitry Andric case Instruction::FPTrunc: 32830b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && 32845ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize > DstScalarBitSize; 32850b57cec5SDimitry Andric case Instruction::FPExt: 32860b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && 32875ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize; 32880b57cec5SDimitry Andric case Instruction::UIToFP: 32890b57cec5SDimitry Andric case Instruction::SIToFP: 32900b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() && 32915ffd83dbSDimitry Andric SrcEC == DstEC; 32920b57cec5SDimitry Andric case Instruction::FPToUI: 32930b57cec5SDimitry Andric case Instruction::FPToSI: 32940b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && 32955ffd83dbSDimitry Andric SrcEC == DstEC; 32960b57cec5SDimitry Andric case Instruction::PtrToInt: 32975ffd83dbSDimitry Andric if (SrcEC != DstEC) 32980b57cec5SDimitry Andric return false; 32990b57cec5SDimitry Andric return SrcTy->isPtrOrPtrVectorTy() && DstTy->isIntOrIntVectorTy(); 33000b57cec5SDimitry Andric case Instruction::IntToPtr: 33015ffd83dbSDimitry Andric if (SrcEC != DstEC) 33020b57cec5SDimitry Andric return false; 33030b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isPtrOrPtrVectorTy(); 33040b57cec5SDimitry Andric case Instruction::BitCast: { 33050b57cec5SDimitry Andric PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType()); 33060b57cec5SDimitry Andric PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType()); 33070b57cec5SDimitry Andric 33080b57cec5SDimitry Andric // BitCast implies a no-op cast of type only. No bits change. 33090b57cec5SDimitry Andric // However, you can't cast pointers to anything but pointers. 33100b57cec5SDimitry Andric if (!SrcPtrTy != !DstPtrTy) 33110b57cec5SDimitry Andric return false; 33120b57cec5SDimitry Andric 33130b57cec5SDimitry Andric // For non-pointer cases, the cast is okay if the source and destination bit 33140b57cec5SDimitry Andric // widths are identical. 33150b57cec5SDimitry Andric if (!SrcPtrTy) 33160b57cec5SDimitry Andric return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); 33170b57cec5SDimitry Andric 33180b57cec5SDimitry Andric // If both are pointers then the address spaces must match. 33190b57cec5SDimitry Andric if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) 33200b57cec5SDimitry Andric return false; 33210b57cec5SDimitry Andric 33220b57cec5SDimitry Andric // A vector of pointers must have the same number of elements. 33235ffd83dbSDimitry Andric if (SrcIsVec && DstIsVec) 33245ffd83dbSDimitry Andric return SrcEC == DstEC; 33255ffd83dbSDimitry Andric if (SrcIsVec) 3326e8d8bef9SDimitry Andric return SrcEC == ElementCount::getFixed(1); 33275ffd83dbSDimitry Andric if (DstIsVec) 3328e8d8bef9SDimitry Andric return DstEC == ElementCount::getFixed(1); 33290b57cec5SDimitry Andric 33300b57cec5SDimitry Andric return true; 33310b57cec5SDimitry Andric } 33320b57cec5SDimitry Andric case Instruction::AddrSpaceCast: { 33330b57cec5SDimitry Andric PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType()); 33340b57cec5SDimitry Andric if (!SrcPtrTy) 33350b57cec5SDimitry Andric return false; 33360b57cec5SDimitry Andric 33370b57cec5SDimitry Andric PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType()); 33380b57cec5SDimitry Andric if (!DstPtrTy) 33390b57cec5SDimitry Andric return false; 33400b57cec5SDimitry Andric 33410b57cec5SDimitry Andric if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) 33420b57cec5SDimitry Andric return false; 33430b57cec5SDimitry Andric 33445ffd83dbSDimitry Andric return SrcEC == DstEC; 33450b57cec5SDimitry Andric } 33460b57cec5SDimitry Andric } 33470b57cec5SDimitry Andric } 33480b57cec5SDimitry Andric 3349*0fca6ea1SDimitry Andric TruncInst::TruncInst(Value *S, Type *Ty, const Twine &Name, 3350*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3351*0fca6ea1SDimitry Andric : CastInst(Ty, Trunc, S, Name, InsertBefore) { 33520b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); 33530b57cec5SDimitry Andric } 33540b57cec5SDimitry Andric 3355*0fca6ea1SDimitry Andric ZExtInst::ZExtInst(Value *S, Type *Ty, const Twine &Name, 3356*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3357*0fca6ea1SDimitry Andric : CastInst(Ty, ZExt, S, Name, InsertBefore) { 33580b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); 33590b57cec5SDimitry Andric } 33600b57cec5SDimitry Andric 3361*0fca6ea1SDimitry Andric SExtInst::SExtInst(Value *S, Type *Ty, const Twine &Name, 3362*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3363*0fca6ea1SDimitry Andric : CastInst(Ty, SExt, S, Name, InsertBefore) { 33640b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); 33650b57cec5SDimitry Andric } 33660b57cec5SDimitry Andric 3367*0fca6ea1SDimitry Andric FPTruncInst::FPTruncInst(Value *S, Type *Ty, const Twine &Name, 3368*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3369*0fca6ea1SDimitry Andric : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { 33700b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); 33710b57cec5SDimitry Andric } 33720b57cec5SDimitry Andric 3373*0fca6ea1SDimitry Andric FPExtInst::FPExtInst(Value *S, Type *Ty, const Twine &Name, 3374*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3375*0fca6ea1SDimitry Andric : CastInst(Ty, FPExt, S, Name, InsertBefore) { 33760b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); 33770b57cec5SDimitry Andric } 33780b57cec5SDimitry Andric 3379*0fca6ea1SDimitry Andric UIToFPInst::UIToFPInst(Value *S, Type *Ty, const Twine &Name, 3380*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3381*0fca6ea1SDimitry Andric : CastInst(Ty, UIToFP, S, Name, InsertBefore) { 33820b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); 33830b57cec5SDimitry Andric } 33840b57cec5SDimitry Andric 3385*0fca6ea1SDimitry Andric SIToFPInst::SIToFPInst(Value *S, Type *Ty, const Twine &Name, 3386*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3387*0fca6ea1SDimitry Andric : CastInst(Ty, SIToFP, S, Name, InsertBefore) { 33880b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); 33890b57cec5SDimitry Andric } 33900b57cec5SDimitry Andric 3391*0fca6ea1SDimitry Andric FPToUIInst::FPToUIInst(Value *S, Type *Ty, const Twine &Name, 3392*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3393*0fca6ea1SDimitry Andric : CastInst(Ty, FPToUI, S, Name, InsertBefore) { 33940b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); 33950b57cec5SDimitry Andric } 33960b57cec5SDimitry Andric 3397*0fca6ea1SDimitry Andric FPToSIInst::FPToSIInst(Value *S, Type *Ty, const Twine &Name, 3398*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3399*0fca6ea1SDimitry Andric : CastInst(Ty, FPToSI, S, Name, InsertBefore) { 34000b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); 34010b57cec5SDimitry Andric } 34020b57cec5SDimitry Andric 3403*0fca6ea1SDimitry Andric PtrToIntInst::PtrToIntInst(Value *S, Type *Ty, const Twine &Name, 3404*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3405*0fca6ea1SDimitry Andric : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { 34060b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); 34070b57cec5SDimitry Andric } 34080b57cec5SDimitry Andric 3409*0fca6ea1SDimitry Andric IntToPtrInst::IntToPtrInst(Value *S, Type *Ty, const Twine &Name, 3410*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3411*0fca6ea1SDimitry Andric : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { 34120b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); 34130b57cec5SDimitry Andric } 34140b57cec5SDimitry Andric 3415*0fca6ea1SDimitry Andric BitCastInst::BitCastInst(Value *S, Type *Ty, const Twine &Name, 3416*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3417*0fca6ea1SDimitry Andric : CastInst(Ty, BitCast, S, Name, InsertBefore) { 34180b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); 34190b57cec5SDimitry Andric } 34200b57cec5SDimitry Andric 3421*0fca6ea1SDimitry Andric AddrSpaceCastInst::AddrSpaceCastInst(Value *S, Type *Ty, const Twine &Name, 3422*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 3423*0fca6ea1SDimitry Andric : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) { 34240b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); 34250b57cec5SDimitry Andric } 34260b57cec5SDimitry Andric 34270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 34280b57cec5SDimitry Andric // CmpInst Classes 34290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS, 3432*0fca6ea1SDimitry Andric Value *RHS, const Twine &Name, InsertPosition InsertBefore, 34330b57cec5SDimitry Andric Instruction *FlagsSource) 3434*0fca6ea1SDimitry Andric : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this), 3435*0fca6ea1SDimitry Andric OperandTraits<CmpInst>::operands(this), InsertBefore) { 34360b57cec5SDimitry Andric Op<0>() = LHS; 34370b57cec5SDimitry Andric Op<1>() = RHS; 34380b57cec5SDimitry Andric setPredicate((Predicate)predicate); 34390b57cec5SDimitry Andric setName(Name); 34400b57cec5SDimitry Andric if (FlagsSource) 34410b57cec5SDimitry Andric copyIRFlags(FlagsSource); 34420b57cec5SDimitry Andric } 34430b57cec5SDimitry Andric 3444*0fca6ea1SDimitry Andric CmpInst *CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, 3445*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) { 34460b57cec5SDimitry Andric if (Op == Instruction::ICmp) { 3447*0fca6ea1SDimitry Andric if (InsertBefore.isValid()) 34480b57cec5SDimitry Andric return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate), 34490b57cec5SDimitry Andric S1, S2, Name); 34500b57cec5SDimitry Andric else 34510b57cec5SDimitry Andric return new ICmpInst(CmpInst::Predicate(predicate), 34520b57cec5SDimitry Andric S1, S2, Name); 34530b57cec5SDimitry Andric } 34540b57cec5SDimitry Andric 3455*0fca6ea1SDimitry Andric if (InsertBefore.isValid()) 34560b57cec5SDimitry Andric return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate), 34570b57cec5SDimitry Andric S1, S2, Name); 34580b57cec5SDimitry Andric else 34590b57cec5SDimitry Andric return new FCmpInst(CmpInst::Predicate(predicate), 34600b57cec5SDimitry Andric S1, S2, Name); 34610b57cec5SDimitry Andric } 34620b57cec5SDimitry Andric 3463*0fca6ea1SDimitry Andric CmpInst *CmpInst::CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1, 3464*0fca6ea1SDimitry Andric Value *S2, 3465*0fca6ea1SDimitry Andric const Instruction *FlagsSource, 3466*0fca6ea1SDimitry Andric const Twine &Name, 3467*0fca6ea1SDimitry Andric InsertPosition InsertBefore) { 3468*0fca6ea1SDimitry Andric CmpInst *Inst = Create(Op, Pred, S1, S2, Name, InsertBefore); 3469*0fca6ea1SDimitry Andric Inst->copyIRFlags(FlagsSource); 3470*0fca6ea1SDimitry Andric return Inst; 34710b57cec5SDimitry Andric } 34720b57cec5SDimitry Andric 34730b57cec5SDimitry Andric void CmpInst::swapOperands() { 34740b57cec5SDimitry Andric if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) 34750b57cec5SDimitry Andric IC->swapOperands(); 34760b57cec5SDimitry Andric else 34770b57cec5SDimitry Andric cast<FCmpInst>(this)->swapOperands(); 34780b57cec5SDimitry Andric } 34790b57cec5SDimitry Andric 34800b57cec5SDimitry Andric bool CmpInst::isCommutative() const { 34810b57cec5SDimitry Andric if (const ICmpInst *IC = dyn_cast<ICmpInst>(this)) 34820b57cec5SDimitry Andric return IC->isCommutative(); 34830b57cec5SDimitry Andric return cast<FCmpInst>(this)->isCommutative(); 34840b57cec5SDimitry Andric } 34850b57cec5SDimitry Andric 3486e8d8bef9SDimitry Andric bool CmpInst::isEquality(Predicate P) { 3487e8d8bef9SDimitry Andric if (ICmpInst::isIntPredicate(P)) 3488e8d8bef9SDimitry Andric return ICmpInst::isEquality(P); 3489e8d8bef9SDimitry Andric if (FCmpInst::isFPPredicate(P)) 3490e8d8bef9SDimitry Andric return FCmpInst::isEquality(P); 3491e8d8bef9SDimitry Andric llvm_unreachable("Unsupported predicate kind"); 34920b57cec5SDimitry Andric } 34930b57cec5SDimitry Andric 34940b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) { 34950b57cec5SDimitry Andric switch (pred) { 34960b57cec5SDimitry Andric default: llvm_unreachable("Unknown cmp predicate!"); 34970b57cec5SDimitry Andric case ICMP_EQ: return ICMP_NE; 34980b57cec5SDimitry Andric case ICMP_NE: return ICMP_EQ; 34990b57cec5SDimitry Andric case ICMP_UGT: return ICMP_ULE; 35000b57cec5SDimitry Andric case ICMP_ULT: return ICMP_UGE; 35010b57cec5SDimitry Andric case ICMP_UGE: return ICMP_ULT; 35020b57cec5SDimitry Andric case ICMP_ULE: return ICMP_UGT; 35030b57cec5SDimitry Andric case ICMP_SGT: return ICMP_SLE; 35040b57cec5SDimitry Andric case ICMP_SLT: return ICMP_SGE; 35050b57cec5SDimitry Andric case ICMP_SGE: return ICMP_SLT; 35060b57cec5SDimitry Andric case ICMP_SLE: return ICMP_SGT; 35070b57cec5SDimitry Andric 35080b57cec5SDimitry Andric case FCMP_OEQ: return FCMP_UNE; 35090b57cec5SDimitry Andric case FCMP_ONE: return FCMP_UEQ; 35100b57cec5SDimitry Andric case FCMP_OGT: return FCMP_ULE; 35110b57cec5SDimitry Andric case FCMP_OLT: return FCMP_UGE; 35120b57cec5SDimitry Andric case FCMP_OGE: return FCMP_ULT; 35130b57cec5SDimitry Andric case FCMP_OLE: return FCMP_UGT; 35140b57cec5SDimitry Andric case FCMP_UEQ: return FCMP_ONE; 35150b57cec5SDimitry Andric case FCMP_UNE: return FCMP_OEQ; 35160b57cec5SDimitry Andric case FCMP_UGT: return FCMP_OLE; 35170b57cec5SDimitry Andric case FCMP_ULT: return FCMP_OGE; 35180b57cec5SDimitry Andric case FCMP_UGE: return FCMP_OLT; 35190b57cec5SDimitry Andric case FCMP_ULE: return FCMP_OGT; 35200b57cec5SDimitry Andric case FCMP_ORD: return FCMP_UNO; 35210b57cec5SDimitry Andric case FCMP_UNO: return FCMP_ORD; 35220b57cec5SDimitry Andric case FCMP_TRUE: return FCMP_FALSE; 35230b57cec5SDimitry Andric case FCMP_FALSE: return FCMP_TRUE; 35240b57cec5SDimitry Andric } 35250b57cec5SDimitry Andric } 35260b57cec5SDimitry Andric 35270b57cec5SDimitry Andric StringRef CmpInst::getPredicateName(Predicate Pred) { 35280b57cec5SDimitry Andric switch (Pred) { 35290b57cec5SDimitry Andric default: return "unknown"; 35300b57cec5SDimitry Andric case FCmpInst::FCMP_FALSE: return "false"; 35310b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: return "oeq"; 35320b57cec5SDimitry Andric case FCmpInst::FCMP_OGT: return "ogt"; 35330b57cec5SDimitry Andric case FCmpInst::FCMP_OGE: return "oge"; 35340b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: return "olt"; 35350b57cec5SDimitry Andric case FCmpInst::FCMP_OLE: return "ole"; 35360b57cec5SDimitry Andric case FCmpInst::FCMP_ONE: return "one"; 35370b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: return "ord"; 35380b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: return "uno"; 35390b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: return "ueq"; 35400b57cec5SDimitry Andric case FCmpInst::FCMP_UGT: return "ugt"; 35410b57cec5SDimitry Andric case FCmpInst::FCMP_UGE: return "uge"; 35420b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: return "ult"; 35430b57cec5SDimitry Andric case FCmpInst::FCMP_ULE: return "ule"; 35440b57cec5SDimitry Andric case FCmpInst::FCMP_UNE: return "une"; 35450b57cec5SDimitry Andric case FCmpInst::FCMP_TRUE: return "true"; 35460b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: return "eq"; 35470b57cec5SDimitry Andric case ICmpInst::ICMP_NE: return "ne"; 35480b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: return "sgt"; 35490b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: return "sge"; 35500b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: return "slt"; 35510b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: return "sle"; 35520b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: return "ugt"; 35530b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: return "uge"; 35540b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: return "ult"; 35550b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: return "ule"; 35560b57cec5SDimitry Andric } 35570b57cec5SDimitry Andric } 35580b57cec5SDimitry Andric 355906c3fb27SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, CmpInst::Predicate Pred) { 356006c3fb27SDimitry Andric OS << CmpInst::getPredicateName(Pred); 356106c3fb27SDimitry Andric return OS; 356206c3fb27SDimitry Andric } 356306c3fb27SDimitry Andric 35640b57cec5SDimitry Andric ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) { 35650b57cec5SDimitry Andric switch (pred) { 35660b57cec5SDimitry Andric default: llvm_unreachable("Unknown icmp predicate!"); 35670b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE: 35680b57cec5SDimitry Andric case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE: 35690b57cec5SDimitry Andric return pred; 35700b57cec5SDimitry Andric case ICMP_UGT: return ICMP_SGT; 35710b57cec5SDimitry Andric case ICMP_ULT: return ICMP_SLT; 35720b57cec5SDimitry Andric case ICMP_UGE: return ICMP_SGE; 35730b57cec5SDimitry Andric case ICMP_ULE: return ICMP_SLE; 35740b57cec5SDimitry Andric } 35750b57cec5SDimitry Andric } 35760b57cec5SDimitry Andric 35770b57cec5SDimitry Andric ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) { 35780b57cec5SDimitry Andric switch (pred) { 35790b57cec5SDimitry Andric default: llvm_unreachable("Unknown icmp predicate!"); 35800b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE: 35810b57cec5SDimitry Andric case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE: 35820b57cec5SDimitry Andric return pred; 35830b57cec5SDimitry Andric case ICMP_SGT: return ICMP_UGT; 35840b57cec5SDimitry Andric case ICMP_SLT: return ICMP_ULT; 35850b57cec5SDimitry Andric case ICMP_SGE: return ICMP_UGE; 35860b57cec5SDimitry Andric case ICMP_SLE: return ICMP_ULE; 35870b57cec5SDimitry Andric } 35880b57cec5SDimitry Andric } 35890b57cec5SDimitry Andric 35900b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { 35910b57cec5SDimitry Andric switch (pred) { 35920b57cec5SDimitry Andric default: llvm_unreachable("Unknown cmp predicate!"); 35930b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE: 35940b57cec5SDimitry Andric return pred; 35950b57cec5SDimitry Andric case ICMP_SGT: return ICMP_SLT; 35960b57cec5SDimitry Andric case ICMP_SLT: return ICMP_SGT; 35970b57cec5SDimitry Andric case ICMP_SGE: return ICMP_SLE; 35980b57cec5SDimitry Andric case ICMP_SLE: return ICMP_SGE; 35990b57cec5SDimitry Andric case ICMP_UGT: return ICMP_ULT; 36000b57cec5SDimitry Andric case ICMP_ULT: return ICMP_UGT; 36010b57cec5SDimitry Andric case ICMP_UGE: return ICMP_ULE; 36020b57cec5SDimitry Andric case ICMP_ULE: return ICMP_UGE; 36030b57cec5SDimitry Andric 36040b57cec5SDimitry Andric case FCMP_FALSE: case FCMP_TRUE: 36050b57cec5SDimitry Andric case FCMP_OEQ: case FCMP_ONE: 36060b57cec5SDimitry Andric case FCMP_UEQ: case FCMP_UNE: 36070b57cec5SDimitry Andric case FCMP_ORD: case FCMP_UNO: 36080b57cec5SDimitry Andric return pred; 36090b57cec5SDimitry Andric case FCMP_OGT: return FCMP_OLT; 36100b57cec5SDimitry Andric case FCMP_OLT: return FCMP_OGT; 36110b57cec5SDimitry Andric case FCMP_OGE: return FCMP_OLE; 36120b57cec5SDimitry Andric case FCMP_OLE: return FCMP_OGE; 36130b57cec5SDimitry Andric case FCMP_UGT: return FCMP_ULT; 36140b57cec5SDimitry Andric case FCMP_ULT: return FCMP_UGT; 36150b57cec5SDimitry Andric case FCMP_UGE: return FCMP_ULE; 36160b57cec5SDimitry Andric case FCMP_ULE: return FCMP_UGE; 36170b57cec5SDimitry Andric } 36180b57cec5SDimitry Andric } 36190b57cec5SDimitry Andric 3620e8d8bef9SDimitry Andric bool CmpInst::isNonStrictPredicate(Predicate pred) { 36210b57cec5SDimitry Andric switch (pred) { 3622e8d8bef9SDimitry Andric case ICMP_SGE: 3623e8d8bef9SDimitry Andric case ICMP_SLE: 3624e8d8bef9SDimitry Andric case ICMP_UGE: 3625e8d8bef9SDimitry Andric case ICMP_ULE: 3626e8d8bef9SDimitry Andric case FCMP_OGE: 3627e8d8bef9SDimitry Andric case FCMP_OLE: 3628e8d8bef9SDimitry Andric case FCMP_UGE: 3629e8d8bef9SDimitry Andric case FCMP_ULE: 3630e8d8bef9SDimitry Andric return true; 3631e8d8bef9SDimitry Andric default: 3632e8d8bef9SDimitry Andric return false; 36330b57cec5SDimitry Andric } 36340b57cec5SDimitry Andric } 36350b57cec5SDimitry Andric 3636e8d8bef9SDimitry Andric bool CmpInst::isStrictPredicate(Predicate pred) { 3637e8d8bef9SDimitry Andric switch (pred) { 3638e8d8bef9SDimitry Andric case ICMP_SGT: 3639e8d8bef9SDimitry Andric case ICMP_SLT: 3640e8d8bef9SDimitry Andric case ICMP_UGT: 3641e8d8bef9SDimitry Andric case ICMP_ULT: 3642e8d8bef9SDimitry Andric case FCMP_OGT: 3643e8d8bef9SDimitry Andric case FCMP_OLT: 3644e8d8bef9SDimitry Andric case FCMP_UGT: 3645e8d8bef9SDimitry Andric case FCMP_ULT: 3646e8d8bef9SDimitry Andric return true; 3647e8d8bef9SDimitry Andric default: 3648e8d8bef9SDimitry Andric return false; 3649e8d8bef9SDimitry Andric } 3650e8d8bef9SDimitry Andric } 3651e8d8bef9SDimitry Andric 3652e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getStrictPredicate(Predicate pred) { 3653e8d8bef9SDimitry Andric switch (pred) { 3654e8d8bef9SDimitry Andric case ICMP_SGE: 3655e8d8bef9SDimitry Andric return ICMP_SGT; 3656e8d8bef9SDimitry Andric case ICMP_SLE: 3657e8d8bef9SDimitry Andric return ICMP_SLT; 3658e8d8bef9SDimitry Andric case ICMP_UGE: 3659e8d8bef9SDimitry Andric return ICMP_UGT; 3660e8d8bef9SDimitry Andric case ICMP_ULE: 3661e8d8bef9SDimitry Andric return ICMP_ULT; 3662e8d8bef9SDimitry Andric case FCMP_OGE: 3663e8d8bef9SDimitry Andric return FCMP_OGT; 3664e8d8bef9SDimitry Andric case FCMP_OLE: 3665e8d8bef9SDimitry Andric return FCMP_OLT; 3666e8d8bef9SDimitry Andric case FCMP_UGE: 3667e8d8bef9SDimitry Andric return FCMP_UGT; 3668e8d8bef9SDimitry Andric case FCMP_ULE: 3669e8d8bef9SDimitry Andric return FCMP_ULT; 3670e8d8bef9SDimitry Andric default: 3671e8d8bef9SDimitry Andric return pred; 3672e8d8bef9SDimitry Andric } 3673e8d8bef9SDimitry Andric } 3674e8d8bef9SDimitry Andric 3675e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) { 3676e8d8bef9SDimitry Andric switch (pred) { 3677e8d8bef9SDimitry Andric case ICMP_SGT: 3678e8d8bef9SDimitry Andric return ICMP_SGE; 3679e8d8bef9SDimitry Andric case ICMP_SLT: 3680e8d8bef9SDimitry Andric return ICMP_SLE; 3681e8d8bef9SDimitry Andric case ICMP_UGT: 3682e8d8bef9SDimitry Andric return ICMP_UGE; 3683e8d8bef9SDimitry Andric case ICMP_ULT: 3684e8d8bef9SDimitry Andric return ICMP_ULE; 3685e8d8bef9SDimitry Andric case FCMP_OGT: 3686e8d8bef9SDimitry Andric return FCMP_OGE; 3687e8d8bef9SDimitry Andric case FCMP_OLT: 3688e8d8bef9SDimitry Andric return FCMP_OLE; 3689e8d8bef9SDimitry Andric case FCMP_UGT: 3690e8d8bef9SDimitry Andric return FCMP_UGE; 3691e8d8bef9SDimitry Andric case FCMP_ULT: 3692e8d8bef9SDimitry Andric return FCMP_ULE; 3693e8d8bef9SDimitry Andric default: 3694e8d8bef9SDimitry Andric return pred; 3695e8d8bef9SDimitry Andric } 3696e8d8bef9SDimitry Andric } 3697e8d8bef9SDimitry Andric 3698e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getFlippedStrictnessPredicate(Predicate pred) { 3699e8d8bef9SDimitry Andric assert(CmpInst::isRelational(pred) && "Call only with relational predicate!"); 3700e8d8bef9SDimitry Andric 3701e8d8bef9SDimitry Andric if (isStrictPredicate(pred)) 3702e8d8bef9SDimitry Andric return getNonStrictPredicate(pred); 3703e8d8bef9SDimitry Andric if (isNonStrictPredicate(pred)) 3704e8d8bef9SDimitry Andric return getStrictPredicate(pred); 3705e8d8bef9SDimitry Andric 3706e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!"); 3707e8d8bef9SDimitry Andric } 3708e8d8bef9SDimitry Andric 37090b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) { 3710e8d8bef9SDimitry Andric assert(CmpInst::isUnsigned(pred) && "Call only with unsigned predicates!"); 37110b57cec5SDimitry Andric 37120b57cec5SDimitry Andric switch (pred) { 37130b57cec5SDimitry Andric default: 37140b57cec5SDimitry Andric llvm_unreachable("Unknown predicate!"); 37150b57cec5SDimitry Andric case CmpInst::ICMP_ULT: 37160b57cec5SDimitry Andric return CmpInst::ICMP_SLT; 37170b57cec5SDimitry Andric case CmpInst::ICMP_ULE: 37180b57cec5SDimitry Andric return CmpInst::ICMP_SLE; 37190b57cec5SDimitry Andric case CmpInst::ICMP_UGT: 37200b57cec5SDimitry Andric return CmpInst::ICMP_SGT; 37210b57cec5SDimitry Andric case CmpInst::ICMP_UGE: 37220b57cec5SDimitry Andric return CmpInst::ICMP_SGE; 37230b57cec5SDimitry Andric } 37240b57cec5SDimitry Andric } 37250b57cec5SDimitry Andric 3726e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getUnsignedPredicate(Predicate pred) { 3727e8d8bef9SDimitry Andric assert(CmpInst::isSigned(pred) && "Call only with signed predicates!"); 3728e8d8bef9SDimitry Andric 3729e8d8bef9SDimitry Andric switch (pred) { 3730e8d8bef9SDimitry Andric default: 3731e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!"); 3732e8d8bef9SDimitry Andric case CmpInst::ICMP_SLT: 3733e8d8bef9SDimitry Andric return CmpInst::ICMP_ULT; 3734e8d8bef9SDimitry Andric case CmpInst::ICMP_SLE: 3735e8d8bef9SDimitry Andric return CmpInst::ICMP_ULE; 3736e8d8bef9SDimitry Andric case CmpInst::ICMP_SGT: 3737e8d8bef9SDimitry Andric return CmpInst::ICMP_UGT; 3738e8d8bef9SDimitry Andric case CmpInst::ICMP_SGE: 3739e8d8bef9SDimitry Andric return CmpInst::ICMP_UGE; 3740e8d8bef9SDimitry Andric } 3741e8d8bef9SDimitry Andric } 3742e8d8bef9SDimitry Andric 37430b57cec5SDimitry Andric bool CmpInst::isUnsigned(Predicate predicate) { 37440b57cec5SDimitry Andric switch (predicate) { 37450b57cec5SDimitry Andric default: return false; 37460b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_UGT: 37470b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: return true; 37480b57cec5SDimitry Andric } 37490b57cec5SDimitry Andric } 37500b57cec5SDimitry Andric 37510b57cec5SDimitry Andric bool CmpInst::isSigned(Predicate predicate) { 37520b57cec5SDimitry Andric switch (predicate) { 37530b57cec5SDimitry Andric default: return false; 37540b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_SGT: 37550b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: return true; 37560b57cec5SDimitry Andric } 37570b57cec5SDimitry Andric } 37580b57cec5SDimitry Andric 3759349cc55cSDimitry Andric bool ICmpInst::compare(const APInt &LHS, const APInt &RHS, 3760349cc55cSDimitry Andric ICmpInst::Predicate Pred) { 3761349cc55cSDimitry Andric assert(ICmpInst::isIntPredicate(Pred) && "Only for integer predicates!"); 3762349cc55cSDimitry Andric switch (Pred) { 3763349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_EQ: 3764349cc55cSDimitry Andric return LHS.eq(RHS); 3765349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_NE: 3766349cc55cSDimitry Andric return LHS.ne(RHS); 3767349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_UGT: 3768349cc55cSDimitry Andric return LHS.ugt(RHS); 3769349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_UGE: 3770349cc55cSDimitry Andric return LHS.uge(RHS); 3771349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_ULT: 3772349cc55cSDimitry Andric return LHS.ult(RHS); 3773349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_ULE: 3774349cc55cSDimitry Andric return LHS.ule(RHS); 3775349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SGT: 3776349cc55cSDimitry Andric return LHS.sgt(RHS); 3777349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SGE: 3778349cc55cSDimitry Andric return LHS.sge(RHS); 3779349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SLT: 3780349cc55cSDimitry Andric return LHS.slt(RHS); 3781349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SLE: 3782349cc55cSDimitry Andric return LHS.sle(RHS); 3783349cc55cSDimitry Andric default: 3784349cc55cSDimitry Andric llvm_unreachable("Unexpected non-integer predicate."); 3785349cc55cSDimitry Andric }; 3786349cc55cSDimitry Andric } 3787349cc55cSDimitry Andric 37880eae32dcSDimitry Andric bool FCmpInst::compare(const APFloat &LHS, const APFloat &RHS, 37890eae32dcSDimitry Andric FCmpInst::Predicate Pred) { 37900eae32dcSDimitry Andric APFloat::cmpResult R = LHS.compare(RHS); 37910eae32dcSDimitry Andric switch (Pred) { 37920eae32dcSDimitry Andric default: 37930eae32dcSDimitry Andric llvm_unreachable("Invalid FCmp Predicate"); 37940eae32dcSDimitry Andric case FCmpInst::FCMP_FALSE: 37950eae32dcSDimitry Andric return false; 37960eae32dcSDimitry Andric case FCmpInst::FCMP_TRUE: 37970eae32dcSDimitry Andric return true; 37980eae32dcSDimitry Andric case FCmpInst::FCMP_UNO: 37990eae32dcSDimitry Andric return R == APFloat::cmpUnordered; 38000eae32dcSDimitry Andric case FCmpInst::FCMP_ORD: 38010eae32dcSDimitry Andric return R != APFloat::cmpUnordered; 38020eae32dcSDimitry Andric case FCmpInst::FCMP_UEQ: 38030eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpEqual; 38040eae32dcSDimitry Andric case FCmpInst::FCMP_OEQ: 38050eae32dcSDimitry Andric return R == APFloat::cmpEqual; 38060eae32dcSDimitry Andric case FCmpInst::FCMP_UNE: 38070eae32dcSDimitry Andric return R != APFloat::cmpEqual; 38080eae32dcSDimitry Andric case FCmpInst::FCMP_ONE: 38090eae32dcSDimitry Andric return R == APFloat::cmpLessThan || R == APFloat::cmpGreaterThan; 38100eae32dcSDimitry Andric case FCmpInst::FCMP_ULT: 38110eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpLessThan; 38120eae32dcSDimitry Andric case FCmpInst::FCMP_OLT: 38130eae32dcSDimitry Andric return R == APFloat::cmpLessThan; 38140eae32dcSDimitry Andric case FCmpInst::FCMP_UGT: 38150eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpGreaterThan; 38160eae32dcSDimitry Andric case FCmpInst::FCMP_OGT: 38170eae32dcSDimitry Andric return R == APFloat::cmpGreaterThan; 38180eae32dcSDimitry Andric case FCmpInst::FCMP_ULE: 38190eae32dcSDimitry Andric return R != APFloat::cmpGreaterThan; 38200eae32dcSDimitry Andric case FCmpInst::FCMP_OLE: 38210eae32dcSDimitry Andric return R == APFloat::cmpLessThan || R == APFloat::cmpEqual; 38220eae32dcSDimitry Andric case FCmpInst::FCMP_UGE: 38230eae32dcSDimitry Andric return R != APFloat::cmpLessThan; 38240eae32dcSDimitry Andric case FCmpInst::FCMP_OGE: 38250eae32dcSDimitry Andric return R == APFloat::cmpGreaterThan || R == APFloat::cmpEqual; 38260eae32dcSDimitry Andric } 38270eae32dcSDimitry Andric } 38280eae32dcSDimitry Andric 3829e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getFlippedSignednessPredicate(Predicate pred) { 3830e8d8bef9SDimitry Andric assert(CmpInst::isRelational(pred) && 3831e8d8bef9SDimitry Andric "Call only with non-equality predicates!"); 3832e8d8bef9SDimitry Andric 3833e8d8bef9SDimitry Andric if (isSigned(pred)) 3834e8d8bef9SDimitry Andric return getUnsignedPredicate(pred); 3835e8d8bef9SDimitry Andric if (isUnsigned(pred)) 3836e8d8bef9SDimitry Andric return getSignedPredicate(pred); 3837e8d8bef9SDimitry Andric 3838e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!"); 3839e8d8bef9SDimitry Andric } 3840e8d8bef9SDimitry Andric 38410b57cec5SDimitry Andric bool CmpInst::isOrdered(Predicate predicate) { 38420b57cec5SDimitry Andric switch (predicate) { 38430b57cec5SDimitry Andric default: return false; 38440b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_OGT: 38450b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLE: 38460b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: return true; 38470b57cec5SDimitry Andric } 38480b57cec5SDimitry Andric } 38490b57cec5SDimitry Andric 38500b57cec5SDimitry Andric bool CmpInst::isUnordered(Predicate predicate) { 38510b57cec5SDimitry Andric switch (predicate) { 38520b57cec5SDimitry Andric default: return false; 38530b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_UGT: 38540b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_ULE: 38550b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: return true; 38560b57cec5SDimitry Andric } 38570b57cec5SDimitry Andric } 38580b57cec5SDimitry Andric 38590b57cec5SDimitry Andric bool CmpInst::isTrueWhenEqual(Predicate predicate) { 38600b57cec5SDimitry Andric switch(predicate) { 38610b57cec5SDimitry Andric default: return false; 38620b57cec5SDimitry Andric case ICMP_EQ: case ICMP_UGE: case ICMP_ULE: case ICMP_SGE: case ICMP_SLE: 38630b57cec5SDimitry Andric case FCMP_TRUE: case FCMP_UEQ: case FCMP_UGE: case FCMP_ULE: return true; 38640b57cec5SDimitry Andric } 38650b57cec5SDimitry Andric } 38660b57cec5SDimitry Andric 38670b57cec5SDimitry Andric bool CmpInst::isFalseWhenEqual(Predicate predicate) { 38680b57cec5SDimitry Andric switch(predicate) { 38690b57cec5SDimitry Andric case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_SGT: case ICMP_SLT: 38700b57cec5SDimitry Andric case FCMP_FALSE: case FCMP_ONE: case FCMP_OGT: case FCMP_OLT: return true; 38710b57cec5SDimitry Andric default: return false; 38720b57cec5SDimitry Andric } 38730b57cec5SDimitry Andric } 38740b57cec5SDimitry Andric 38750b57cec5SDimitry Andric bool CmpInst::isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) { 38760b57cec5SDimitry Andric // If the predicates match, then we know the first condition implies the 38770b57cec5SDimitry Andric // second is true. 38780b57cec5SDimitry Andric if (Pred1 == Pred2) 38790b57cec5SDimitry Andric return true; 38800b57cec5SDimitry Andric 38810b57cec5SDimitry Andric switch (Pred1) { 38820b57cec5SDimitry Andric default: 38830b57cec5SDimitry Andric break; 38840b57cec5SDimitry Andric case ICMP_EQ: 38850b57cec5SDimitry Andric // A == B implies A >=u B, A <=u B, A >=s B, and A <=s B are true. 38860b57cec5SDimitry Andric return Pred2 == ICMP_UGE || Pred2 == ICMP_ULE || Pred2 == ICMP_SGE || 38870b57cec5SDimitry Andric Pred2 == ICMP_SLE; 38880b57cec5SDimitry Andric case ICMP_UGT: // A >u B implies A != B and A >=u B are true. 38890b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_UGE; 38900b57cec5SDimitry Andric case ICMP_ULT: // A <u B implies A != B and A <=u B are true. 38910b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_ULE; 38920b57cec5SDimitry Andric case ICMP_SGT: // A >s B implies A != B and A >=s B are true. 38930b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_SGE; 38940b57cec5SDimitry Andric case ICMP_SLT: // A <s B implies A != B and A <=s B are true. 38950b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_SLE; 38960b57cec5SDimitry Andric } 38970b57cec5SDimitry Andric return false; 38980b57cec5SDimitry Andric } 38990b57cec5SDimitry Andric 39000b57cec5SDimitry Andric bool CmpInst::isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2) { 39010b57cec5SDimitry Andric return isImpliedTrueByMatchingCmp(Pred1, getInversePredicate(Pred2)); 39020b57cec5SDimitry Andric } 39030b57cec5SDimitry Andric 39040b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 39050b57cec5SDimitry Andric // SwitchInst Implementation 39060b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 39070b57cec5SDimitry Andric 39080b57cec5SDimitry Andric void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) { 39090b57cec5SDimitry Andric assert(Value && Default && NumReserved); 39100b57cec5SDimitry Andric ReservedSpace = NumReserved; 39110b57cec5SDimitry Andric setNumHungOffUseOperands(2); 39120b57cec5SDimitry Andric allocHungoffUses(ReservedSpace); 39130b57cec5SDimitry Andric 39140b57cec5SDimitry Andric Op<0>() = Value; 39150b57cec5SDimitry Andric Op<1>() = Default; 39160b57cec5SDimitry Andric } 39170b57cec5SDimitry Andric 39180b57cec5SDimitry Andric /// SwitchInst ctor - Create a new switch instruction, specifying a value to 39190b57cec5SDimitry Andric /// switch on and a default destination. The number of additional cases can 39200b57cec5SDimitry Andric /// be specified here to make memory allocation more efficient. This 39210b57cec5SDimitry Andric /// constructor can also autoinsert before another instruction. 39220b57cec5SDimitry Andric SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, 3923*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 39240b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch, 39250b57cec5SDimitry Andric nullptr, 0, InsertBefore) { 39260b57cec5SDimitry Andric init(Value, Default, 2+NumCases*2); 39270b57cec5SDimitry Andric } 39280b57cec5SDimitry Andric 39290b57cec5SDimitry Andric SwitchInst::SwitchInst(const SwitchInst &SI) 39300b57cec5SDimitry Andric : Instruction(SI.getType(), Instruction::Switch, nullptr, 0) { 39310b57cec5SDimitry Andric init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands()); 39320b57cec5SDimitry Andric setNumHungOffUseOperands(SI.getNumOperands()); 39330b57cec5SDimitry Andric Use *OL = getOperandList(); 39340b57cec5SDimitry Andric const Use *InOL = SI.getOperandList(); 39350b57cec5SDimitry Andric for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) { 39360b57cec5SDimitry Andric OL[i] = InOL[i]; 39370b57cec5SDimitry Andric OL[i+1] = InOL[i+1]; 39380b57cec5SDimitry Andric } 39390b57cec5SDimitry Andric SubclassOptionalData = SI.SubclassOptionalData; 39400b57cec5SDimitry Andric } 39410b57cec5SDimitry Andric 39420b57cec5SDimitry Andric /// addCase - Add an entry to the switch instruction... 39430b57cec5SDimitry Andric /// 39440b57cec5SDimitry Andric void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { 39450b57cec5SDimitry Andric unsigned NewCaseIdx = getNumCases(); 39460b57cec5SDimitry Andric unsigned OpNo = getNumOperands(); 39470b57cec5SDimitry Andric if (OpNo+2 > ReservedSpace) 39480b57cec5SDimitry Andric growOperands(); // Get more space! 39490b57cec5SDimitry Andric // Initialize some new operands. 39500b57cec5SDimitry Andric assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); 39510b57cec5SDimitry Andric setNumHungOffUseOperands(OpNo+2); 39520b57cec5SDimitry Andric CaseHandle Case(this, NewCaseIdx); 39530b57cec5SDimitry Andric Case.setValue(OnVal); 39540b57cec5SDimitry Andric Case.setSuccessor(Dest); 39550b57cec5SDimitry Andric } 39560b57cec5SDimitry Andric 39570b57cec5SDimitry Andric /// removeCase - This method removes the specified case and its successor 39580b57cec5SDimitry Andric /// from the switch instruction. 39590b57cec5SDimitry Andric SwitchInst::CaseIt SwitchInst::removeCase(CaseIt I) { 39600b57cec5SDimitry Andric unsigned idx = I->getCaseIndex(); 39610b57cec5SDimitry Andric 39620b57cec5SDimitry Andric assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!"); 39630b57cec5SDimitry Andric 39640b57cec5SDimitry Andric unsigned NumOps = getNumOperands(); 39650b57cec5SDimitry Andric Use *OL = getOperandList(); 39660b57cec5SDimitry Andric 39670b57cec5SDimitry Andric // Overwrite this case with the end of the list. 39680b57cec5SDimitry Andric if (2 + (idx + 1) * 2 != NumOps) { 39690b57cec5SDimitry Andric OL[2 + idx * 2] = OL[NumOps - 2]; 39700b57cec5SDimitry Andric OL[2 + idx * 2 + 1] = OL[NumOps - 1]; 39710b57cec5SDimitry Andric } 39720b57cec5SDimitry Andric 39730b57cec5SDimitry Andric // Nuke the last value. 39740b57cec5SDimitry Andric OL[NumOps-2].set(nullptr); 39750b57cec5SDimitry Andric OL[NumOps-2+1].set(nullptr); 39760b57cec5SDimitry Andric setNumHungOffUseOperands(NumOps-2); 39770b57cec5SDimitry Andric 39780b57cec5SDimitry Andric return CaseIt(this, idx); 39790b57cec5SDimitry Andric } 39800b57cec5SDimitry Andric 39810b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response 39820b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 3 times. 39830b57cec5SDimitry Andric /// 39840b57cec5SDimitry Andric void SwitchInst::growOperands() { 39850b57cec5SDimitry Andric unsigned e = getNumOperands(); 39860b57cec5SDimitry Andric unsigned NumOps = e*3; 39870b57cec5SDimitry Andric 39880b57cec5SDimitry Andric ReservedSpace = NumOps; 39890b57cec5SDimitry Andric growHungoffUses(ReservedSpace); 39900b57cec5SDimitry Andric } 39910b57cec5SDimitry Andric 39920b57cec5SDimitry Andric MDNode *SwitchInstProfUpdateWrapper::buildProfBranchWeightsMD() { 39938bcb0991SDimitry Andric assert(Changed && "called only if metadata has changed"); 39940b57cec5SDimitry Andric 39950b57cec5SDimitry Andric if (!Weights) 39960b57cec5SDimitry Andric return nullptr; 39970b57cec5SDimitry Andric 39980b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() && 39990b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors"); 40000b57cec5SDimitry Andric 4001bdd1243dSDimitry Andric bool AllZeroes = all_of(*Weights, [](uint32_t W) { return W == 0; }); 40020b57cec5SDimitry Andric 4003bdd1243dSDimitry Andric if (AllZeroes || Weights->size() < 2) 40040b57cec5SDimitry Andric return nullptr; 40050b57cec5SDimitry Andric 40060b57cec5SDimitry Andric return MDBuilder(SI.getParent()->getContext()).createBranchWeights(*Weights); 40070b57cec5SDimitry Andric } 40080b57cec5SDimitry Andric 40090b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::init() { 4010bdd1243dSDimitry Andric MDNode *ProfileData = getBranchWeightMDNode(SI); 40118bcb0991SDimitry Andric if (!ProfileData) 40120b57cec5SDimitry Andric return; 40130b57cec5SDimitry Andric 4014*0fca6ea1SDimitry Andric if (getNumBranchWeights(*ProfileData) != SI.getNumSuccessors()) { 40150b57cec5SDimitry Andric llvm_unreachable("number of prof branch_weights metadata operands does " 40160b57cec5SDimitry Andric "not correspond to number of succesors"); 40170b57cec5SDimitry Andric } 40180b57cec5SDimitry Andric 40190b57cec5SDimitry Andric SmallVector<uint32_t, 8> Weights; 4020bdd1243dSDimitry Andric if (!extractBranchWeights(ProfileData, Weights)) 4021bdd1243dSDimitry Andric return; 40220b57cec5SDimitry Andric this->Weights = std::move(Weights); 40230b57cec5SDimitry Andric } 40240b57cec5SDimitry Andric 40250b57cec5SDimitry Andric SwitchInst::CaseIt 40260b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::removeCase(SwitchInst::CaseIt I) { 40270b57cec5SDimitry Andric if (Weights) { 40280b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() && 40290b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors"); 40308bcb0991SDimitry Andric Changed = true; 40310b57cec5SDimitry Andric // Copy the last case to the place of the removed one and shrink. 40320b57cec5SDimitry Andric // This is tightly coupled with the way SwitchInst::removeCase() removes 40330b57cec5SDimitry Andric // the cases in SwitchInst::removeCase(CaseIt). 4034bdd1243dSDimitry Andric (*Weights)[I->getCaseIndex() + 1] = Weights->back(); 4035bdd1243dSDimitry Andric Weights->pop_back(); 40360b57cec5SDimitry Andric } 40370b57cec5SDimitry Andric return SI.removeCase(I); 40380b57cec5SDimitry Andric } 40390b57cec5SDimitry Andric 40400b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::addCase( 40410b57cec5SDimitry Andric ConstantInt *OnVal, BasicBlock *Dest, 40420b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt W) { 40430b57cec5SDimitry Andric SI.addCase(OnVal, Dest); 40440b57cec5SDimitry Andric 40450b57cec5SDimitry Andric if (!Weights && W && *W) { 40468bcb0991SDimitry Andric Changed = true; 40470b57cec5SDimitry Andric Weights = SmallVector<uint32_t, 8>(SI.getNumSuccessors(), 0); 4048bdd1243dSDimitry Andric (*Weights)[SI.getNumSuccessors() - 1] = *W; 40490b57cec5SDimitry Andric } else if (Weights) { 40508bcb0991SDimitry Andric Changed = true; 4051bdd1243dSDimitry Andric Weights->push_back(W.value_or(0)); 40520b57cec5SDimitry Andric } 40530b57cec5SDimitry Andric if (Weights) 40540b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() && 40550b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors"); 40560b57cec5SDimitry Andric } 40570b57cec5SDimitry Andric 40585f757f3fSDimitry Andric Instruction::InstListType::iterator 40590b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::eraseFromParent() { 40600b57cec5SDimitry Andric // Instruction is erased. Mark as unchanged to not touch it in the destructor. 40618bcb0991SDimitry Andric Changed = false; 40620b57cec5SDimitry Andric if (Weights) 40630b57cec5SDimitry Andric Weights->resize(0); 40640b57cec5SDimitry Andric return SI.eraseFromParent(); 40650b57cec5SDimitry Andric } 40660b57cec5SDimitry Andric 40670b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt 40680b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::getSuccessorWeight(unsigned idx) { 40690b57cec5SDimitry Andric if (!Weights) 4070bdd1243dSDimitry Andric return std::nullopt; 407181ad6265SDimitry Andric return (*Weights)[idx]; 40720b57cec5SDimitry Andric } 40730b57cec5SDimitry Andric 40740b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::setSuccessorWeight( 40750b57cec5SDimitry Andric unsigned idx, SwitchInstProfUpdateWrapper::CaseWeightOpt W) { 40768bcb0991SDimitry Andric if (!W) 40770b57cec5SDimitry Andric return; 40780b57cec5SDimitry Andric 40790b57cec5SDimitry Andric if (!Weights && *W) 40800b57cec5SDimitry Andric Weights = SmallVector<uint32_t, 8>(SI.getNumSuccessors(), 0); 40810b57cec5SDimitry Andric 40820b57cec5SDimitry Andric if (Weights) { 408381ad6265SDimitry Andric auto &OldW = (*Weights)[idx]; 40840b57cec5SDimitry Andric if (*W != OldW) { 40858bcb0991SDimitry Andric Changed = true; 40860b57cec5SDimitry Andric OldW = *W; 40870b57cec5SDimitry Andric } 40880b57cec5SDimitry Andric } 40890b57cec5SDimitry Andric } 40900b57cec5SDimitry Andric 40910b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt 40920b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::getSuccessorWeight(const SwitchInst &SI, 40930b57cec5SDimitry Andric unsigned idx) { 4094bdd1243dSDimitry Andric if (MDNode *ProfileData = getBranchWeightMDNode(SI)) 40950b57cec5SDimitry Andric if (ProfileData->getNumOperands() == SI.getNumSuccessors() + 1) 40960b57cec5SDimitry Andric return mdconst::extract<ConstantInt>(ProfileData->getOperand(idx + 1)) 40970b57cec5SDimitry Andric ->getValue() 40980b57cec5SDimitry Andric .getZExtValue(); 40990b57cec5SDimitry Andric 4100bdd1243dSDimitry Andric return std::nullopt; 41010b57cec5SDimitry Andric } 41020b57cec5SDimitry Andric 41030b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 41040b57cec5SDimitry Andric // IndirectBrInst Implementation 41050b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 41060b57cec5SDimitry Andric 41070b57cec5SDimitry Andric void IndirectBrInst::init(Value *Address, unsigned NumDests) { 41080b57cec5SDimitry Andric assert(Address && Address->getType()->isPointerTy() && 41090b57cec5SDimitry Andric "Address of indirectbr must be a pointer"); 41100b57cec5SDimitry Andric ReservedSpace = 1+NumDests; 41110b57cec5SDimitry Andric setNumHungOffUseOperands(1); 41120b57cec5SDimitry Andric allocHungoffUses(ReservedSpace); 41130b57cec5SDimitry Andric 41140b57cec5SDimitry Andric Op<0>() = Address; 41150b57cec5SDimitry Andric } 41160b57cec5SDimitry Andric 41170b57cec5SDimitry Andric 41180b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response 41190b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 2 times. 41200b57cec5SDimitry Andric /// 41210b57cec5SDimitry Andric void IndirectBrInst::growOperands() { 41220b57cec5SDimitry Andric unsigned e = getNumOperands(); 41230b57cec5SDimitry Andric unsigned NumOps = e*2; 41240b57cec5SDimitry Andric 41250b57cec5SDimitry Andric ReservedSpace = NumOps; 41260b57cec5SDimitry Andric growHungoffUses(ReservedSpace); 41270b57cec5SDimitry Andric } 41280b57cec5SDimitry Andric 41290b57cec5SDimitry Andric IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, 4130*0fca6ea1SDimitry Andric InsertPosition InsertBefore) 41310b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Address->getContext()), 41320b57cec5SDimitry Andric Instruction::IndirectBr, nullptr, 0, InsertBefore) { 41330b57cec5SDimitry Andric init(Address, NumCases); 41340b57cec5SDimitry Andric } 41350b57cec5SDimitry Andric 41360b57cec5SDimitry Andric IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI) 41370b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr, 41380b57cec5SDimitry Andric nullptr, IBI.getNumOperands()) { 41390b57cec5SDimitry Andric allocHungoffUses(IBI.getNumOperands()); 41400b57cec5SDimitry Andric Use *OL = getOperandList(); 41410b57cec5SDimitry Andric const Use *InOL = IBI.getOperandList(); 41420b57cec5SDimitry Andric for (unsigned i = 0, E = IBI.getNumOperands(); i != E; ++i) 41430b57cec5SDimitry Andric OL[i] = InOL[i]; 41440b57cec5SDimitry Andric SubclassOptionalData = IBI.SubclassOptionalData; 41450b57cec5SDimitry Andric } 41460b57cec5SDimitry Andric 41470b57cec5SDimitry Andric /// addDestination - Add a destination. 41480b57cec5SDimitry Andric /// 41490b57cec5SDimitry Andric void IndirectBrInst::addDestination(BasicBlock *DestBB) { 41500b57cec5SDimitry Andric unsigned OpNo = getNumOperands(); 41510b57cec5SDimitry Andric if (OpNo+1 > ReservedSpace) 41520b57cec5SDimitry Andric growOperands(); // Get more space! 41530b57cec5SDimitry Andric // Initialize some new operands. 41540b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!"); 41550b57cec5SDimitry Andric setNumHungOffUseOperands(OpNo+1); 41560b57cec5SDimitry Andric getOperandList()[OpNo] = DestBB; 41570b57cec5SDimitry Andric } 41580b57cec5SDimitry Andric 41590b57cec5SDimitry Andric /// removeDestination - This method removes the specified successor from the 41600b57cec5SDimitry Andric /// indirectbr instruction. 41610b57cec5SDimitry Andric void IndirectBrInst::removeDestination(unsigned idx) { 41620b57cec5SDimitry Andric assert(idx < getNumOperands()-1 && "Successor index out of range!"); 41630b57cec5SDimitry Andric 41640b57cec5SDimitry Andric unsigned NumOps = getNumOperands(); 41650b57cec5SDimitry Andric Use *OL = getOperandList(); 41660b57cec5SDimitry Andric 41670b57cec5SDimitry Andric // Replace this value with the last one. 41680b57cec5SDimitry Andric OL[idx+1] = OL[NumOps-1]; 41690b57cec5SDimitry Andric 41700b57cec5SDimitry Andric // Nuke the last value. 41710b57cec5SDimitry Andric OL[NumOps-1].set(nullptr); 41720b57cec5SDimitry Andric setNumHungOffUseOperands(NumOps-1); 41730b57cec5SDimitry Andric } 41740b57cec5SDimitry Andric 41750b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4176480093f4SDimitry Andric // FreezeInst Implementation 4177480093f4SDimitry Andric //===----------------------------------------------------------------------===// 4178480093f4SDimitry Andric 4179*0fca6ea1SDimitry Andric FreezeInst::FreezeInst(Value *S, const Twine &Name, InsertPosition InsertBefore) 4180480093f4SDimitry Andric : UnaryInstruction(S->getType(), Freeze, S, InsertBefore) { 4181480093f4SDimitry Andric setName(Name); 4182480093f4SDimitry Andric } 4183480093f4SDimitry Andric 4184480093f4SDimitry Andric //===----------------------------------------------------------------------===// 41850b57cec5SDimitry Andric // cloneImpl() implementations 41860b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 41870b57cec5SDimitry Andric 41880b57cec5SDimitry Andric // Define these methods here so vtables don't get emitted into every translation 41890b57cec5SDimitry Andric // unit that uses these classes. 41900b57cec5SDimitry Andric 41910b57cec5SDimitry Andric GetElementPtrInst *GetElementPtrInst::cloneImpl() const { 41920b57cec5SDimitry Andric return new (getNumOperands()) GetElementPtrInst(*this); 41930b57cec5SDimitry Andric } 41940b57cec5SDimitry Andric 41950b57cec5SDimitry Andric UnaryOperator *UnaryOperator::cloneImpl() const { 41960b57cec5SDimitry Andric return Create(getOpcode(), Op<0>()); 41970b57cec5SDimitry Andric } 41980b57cec5SDimitry Andric 41990b57cec5SDimitry Andric BinaryOperator *BinaryOperator::cloneImpl() const { 42000b57cec5SDimitry Andric return Create(getOpcode(), Op<0>(), Op<1>()); 42010b57cec5SDimitry Andric } 42020b57cec5SDimitry Andric 42030b57cec5SDimitry Andric FCmpInst *FCmpInst::cloneImpl() const { 42040b57cec5SDimitry Andric return new FCmpInst(getPredicate(), Op<0>(), Op<1>()); 42050b57cec5SDimitry Andric } 42060b57cec5SDimitry Andric 42070b57cec5SDimitry Andric ICmpInst *ICmpInst::cloneImpl() const { 42080b57cec5SDimitry Andric return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); 42090b57cec5SDimitry Andric } 42100b57cec5SDimitry Andric 42110b57cec5SDimitry Andric ExtractValueInst *ExtractValueInst::cloneImpl() const { 42120b57cec5SDimitry Andric return new ExtractValueInst(*this); 42130b57cec5SDimitry Andric } 42140b57cec5SDimitry Andric 42150b57cec5SDimitry Andric InsertValueInst *InsertValueInst::cloneImpl() const { 42160b57cec5SDimitry Andric return new InsertValueInst(*this); 42170b57cec5SDimitry Andric } 42180b57cec5SDimitry Andric 42190b57cec5SDimitry Andric AllocaInst *AllocaInst::cloneImpl() const { 4220bdd1243dSDimitry Andric AllocaInst *Result = new AllocaInst(getAllocatedType(), getAddressSpace(), 42215ffd83dbSDimitry Andric getOperand(0), getAlign()); 42220b57cec5SDimitry Andric Result->setUsedWithInAlloca(isUsedWithInAlloca()); 42230b57cec5SDimitry Andric Result->setSwiftError(isSwiftError()); 42240b57cec5SDimitry Andric return Result; 42250b57cec5SDimitry Andric } 42260b57cec5SDimitry Andric 42270b57cec5SDimitry Andric LoadInst *LoadInst::cloneImpl() const { 42280b57cec5SDimitry Andric return new LoadInst(getType(), getOperand(0), Twine(), isVolatile(), 42295ffd83dbSDimitry Andric getAlign(), getOrdering(), getSyncScopeID()); 42300b57cec5SDimitry Andric } 42310b57cec5SDimitry Andric 42320b57cec5SDimitry Andric StoreInst *StoreInst::cloneImpl() const { 42335ffd83dbSDimitry Andric return new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlign(), 42345ffd83dbSDimitry Andric getOrdering(), getSyncScopeID()); 42350b57cec5SDimitry Andric } 42360b57cec5SDimitry Andric 42370b57cec5SDimitry Andric AtomicCmpXchgInst *AtomicCmpXchgInst::cloneImpl() const { 42385ffd83dbSDimitry Andric AtomicCmpXchgInst *Result = new AtomicCmpXchgInst( 42395ffd83dbSDimitry Andric getOperand(0), getOperand(1), getOperand(2), getAlign(), 42405ffd83dbSDimitry Andric getSuccessOrdering(), getFailureOrdering(), getSyncScopeID()); 42410b57cec5SDimitry Andric Result->setVolatile(isVolatile()); 42420b57cec5SDimitry Andric Result->setWeak(isWeak()); 42430b57cec5SDimitry Andric return Result; 42440b57cec5SDimitry Andric } 42450b57cec5SDimitry Andric 42460b57cec5SDimitry Andric AtomicRMWInst *AtomicRMWInst::cloneImpl() const { 42470b57cec5SDimitry Andric AtomicRMWInst *Result = 42480b57cec5SDimitry Andric new AtomicRMWInst(getOperation(), getOperand(0), getOperand(1), 42495ffd83dbSDimitry Andric getAlign(), getOrdering(), getSyncScopeID()); 42500b57cec5SDimitry Andric Result->setVolatile(isVolatile()); 42510b57cec5SDimitry Andric return Result; 42520b57cec5SDimitry Andric } 42530b57cec5SDimitry Andric 42540b57cec5SDimitry Andric FenceInst *FenceInst::cloneImpl() const { 42550b57cec5SDimitry Andric return new FenceInst(getContext(), getOrdering(), getSyncScopeID()); 42560b57cec5SDimitry Andric } 42570b57cec5SDimitry Andric 42580b57cec5SDimitry Andric TruncInst *TruncInst::cloneImpl() const { 42590b57cec5SDimitry Andric return new TruncInst(getOperand(0), getType()); 42600b57cec5SDimitry Andric } 42610b57cec5SDimitry Andric 42620b57cec5SDimitry Andric ZExtInst *ZExtInst::cloneImpl() const { 42630b57cec5SDimitry Andric return new ZExtInst(getOperand(0), getType()); 42640b57cec5SDimitry Andric } 42650b57cec5SDimitry Andric 42660b57cec5SDimitry Andric SExtInst *SExtInst::cloneImpl() const { 42670b57cec5SDimitry Andric return new SExtInst(getOperand(0), getType()); 42680b57cec5SDimitry Andric } 42690b57cec5SDimitry Andric 42700b57cec5SDimitry Andric FPTruncInst *FPTruncInst::cloneImpl() const { 42710b57cec5SDimitry Andric return new FPTruncInst(getOperand(0), getType()); 42720b57cec5SDimitry Andric } 42730b57cec5SDimitry Andric 42740b57cec5SDimitry Andric FPExtInst *FPExtInst::cloneImpl() const { 42750b57cec5SDimitry Andric return new FPExtInst(getOperand(0), getType()); 42760b57cec5SDimitry Andric } 42770b57cec5SDimitry Andric 42780b57cec5SDimitry Andric UIToFPInst *UIToFPInst::cloneImpl() const { 42790b57cec5SDimitry Andric return new UIToFPInst(getOperand(0), getType()); 42800b57cec5SDimitry Andric } 42810b57cec5SDimitry Andric 42820b57cec5SDimitry Andric SIToFPInst *SIToFPInst::cloneImpl() const { 42830b57cec5SDimitry Andric return new SIToFPInst(getOperand(0), getType()); 42840b57cec5SDimitry Andric } 42850b57cec5SDimitry Andric 42860b57cec5SDimitry Andric FPToUIInst *FPToUIInst::cloneImpl() const { 42870b57cec5SDimitry Andric return new FPToUIInst(getOperand(0), getType()); 42880b57cec5SDimitry Andric } 42890b57cec5SDimitry Andric 42900b57cec5SDimitry Andric FPToSIInst *FPToSIInst::cloneImpl() const { 42910b57cec5SDimitry Andric return new FPToSIInst(getOperand(0), getType()); 42920b57cec5SDimitry Andric } 42930b57cec5SDimitry Andric 42940b57cec5SDimitry Andric PtrToIntInst *PtrToIntInst::cloneImpl() const { 42950b57cec5SDimitry Andric return new PtrToIntInst(getOperand(0), getType()); 42960b57cec5SDimitry Andric } 42970b57cec5SDimitry Andric 42980b57cec5SDimitry Andric IntToPtrInst *IntToPtrInst::cloneImpl() const { 42990b57cec5SDimitry Andric return new IntToPtrInst(getOperand(0), getType()); 43000b57cec5SDimitry Andric } 43010b57cec5SDimitry Andric 43020b57cec5SDimitry Andric BitCastInst *BitCastInst::cloneImpl() const { 43030b57cec5SDimitry Andric return new BitCastInst(getOperand(0), getType()); 43040b57cec5SDimitry Andric } 43050b57cec5SDimitry Andric 43060b57cec5SDimitry Andric AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const { 43070b57cec5SDimitry Andric return new AddrSpaceCastInst(getOperand(0), getType()); 43080b57cec5SDimitry Andric } 43090b57cec5SDimitry Andric 43100b57cec5SDimitry Andric CallInst *CallInst::cloneImpl() const { 43110b57cec5SDimitry Andric if (hasOperandBundles()) { 43120b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo); 43130b57cec5SDimitry Andric return new(getNumOperands(), DescriptorBytes) CallInst(*this); 43140b57cec5SDimitry Andric } 43150b57cec5SDimitry Andric return new(getNumOperands()) CallInst(*this); 43160b57cec5SDimitry Andric } 43170b57cec5SDimitry Andric 43180b57cec5SDimitry Andric SelectInst *SelectInst::cloneImpl() const { 43190b57cec5SDimitry Andric return SelectInst::Create(getOperand(0), getOperand(1), getOperand(2)); 43200b57cec5SDimitry Andric } 43210b57cec5SDimitry Andric 43220b57cec5SDimitry Andric VAArgInst *VAArgInst::cloneImpl() const { 43230b57cec5SDimitry Andric return new VAArgInst(getOperand(0), getType()); 43240b57cec5SDimitry Andric } 43250b57cec5SDimitry Andric 43260b57cec5SDimitry Andric ExtractElementInst *ExtractElementInst::cloneImpl() const { 43270b57cec5SDimitry Andric return ExtractElementInst::Create(getOperand(0), getOperand(1)); 43280b57cec5SDimitry Andric } 43290b57cec5SDimitry Andric 43300b57cec5SDimitry Andric InsertElementInst *InsertElementInst::cloneImpl() const { 43310b57cec5SDimitry Andric return InsertElementInst::Create(getOperand(0), getOperand(1), getOperand(2)); 43320b57cec5SDimitry Andric } 43330b57cec5SDimitry Andric 43340b57cec5SDimitry Andric ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const { 43355ffd83dbSDimitry Andric return new ShuffleVectorInst(getOperand(0), getOperand(1), getShuffleMask()); 43360b57cec5SDimitry Andric } 43370b57cec5SDimitry Andric 43380b57cec5SDimitry Andric PHINode *PHINode::cloneImpl() const { return new PHINode(*this); } 43390b57cec5SDimitry Andric 43400b57cec5SDimitry Andric LandingPadInst *LandingPadInst::cloneImpl() const { 43410b57cec5SDimitry Andric return new LandingPadInst(*this); 43420b57cec5SDimitry Andric } 43430b57cec5SDimitry Andric 43440b57cec5SDimitry Andric ReturnInst *ReturnInst::cloneImpl() const { 43450b57cec5SDimitry Andric return new(getNumOperands()) ReturnInst(*this); 43460b57cec5SDimitry Andric } 43470b57cec5SDimitry Andric 43480b57cec5SDimitry Andric BranchInst *BranchInst::cloneImpl() const { 43490b57cec5SDimitry Andric return new(getNumOperands()) BranchInst(*this); 43500b57cec5SDimitry Andric } 43510b57cec5SDimitry Andric 43520b57cec5SDimitry Andric SwitchInst *SwitchInst::cloneImpl() const { return new SwitchInst(*this); } 43530b57cec5SDimitry Andric 43540b57cec5SDimitry Andric IndirectBrInst *IndirectBrInst::cloneImpl() const { 43550b57cec5SDimitry Andric return new IndirectBrInst(*this); 43560b57cec5SDimitry Andric } 43570b57cec5SDimitry Andric 43580b57cec5SDimitry Andric InvokeInst *InvokeInst::cloneImpl() const { 43590b57cec5SDimitry Andric if (hasOperandBundles()) { 43600b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo); 43610b57cec5SDimitry Andric return new(getNumOperands(), DescriptorBytes) InvokeInst(*this); 43620b57cec5SDimitry Andric } 43630b57cec5SDimitry Andric return new(getNumOperands()) InvokeInst(*this); 43640b57cec5SDimitry Andric } 43650b57cec5SDimitry Andric 43660b57cec5SDimitry Andric CallBrInst *CallBrInst::cloneImpl() const { 43670b57cec5SDimitry Andric if (hasOperandBundles()) { 43680b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo); 43690b57cec5SDimitry Andric return new (getNumOperands(), DescriptorBytes) CallBrInst(*this); 43700b57cec5SDimitry Andric } 43710b57cec5SDimitry Andric return new (getNumOperands()) CallBrInst(*this); 43720b57cec5SDimitry Andric } 43730b57cec5SDimitry Andric 43740b57cec5SDimitry Andric ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); } 43750b57cec5SDimitry Andric 43760b57cec5SDimitry Andric CleanupReturnInst *CleanupReturnInst::cloneImpl() const { 43770b57cec5SDimitry Andric return new (getNumOperands()) CleanupReturnInst(*this); 43780b57cec5SDimitry Andric } 43790b57cec5SDimitry Andric 43800b57cec5SDimitry Andric CatchReturnInst *CatchReturnInst::cloneImpl() const { 43810b57cec5SDimitry Andric return new (getNumOperands()) CatchReturnInst(*this); 43820b57cec5SDimitry Andric } 43830b57cec5SDimitry Andric 43840b57cec5SDimitry Andric CatchSwitchInst *CatchSwitchInst::cloneImpl() const { 43850b57cec5SDimitry Andric return new CatchSwitchInst(*this); 43860b57cec5SDimitry Andric } 43870b57cec5SDimitry Andric 43880b57cec5SDimitry Andric FuncletPadInst *FuncletPadInst::cloneImpl() const { 43890b57cec5SDimitry Andric return new (getNumOperands()) FuncletPadInst(*this); 43900b57cec5SDimitry Andric } 43910b57cec5SDimitry Andric 43920b57cec5SDimitry Andric UnreachableInst *UnreachableInst::cloneImpl() const { 43930b57cec5SDimitry Andric LLVMContext &Context = getContext(); 43940b57cec5SDimitry Andric return new UnreachableInst(Context); 43950b57cec5SDimitry Andric } 4396480093f4SDimitry Andric 4397480093f4SDimitry Andric FreezeInst *FreezeInst::cloneImpl() const { 4398480093f4SDimitry Andric return new FreezeInst(getOperand(0)); 4399480093f4SDimitry Andric } 4400