bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
const Value *V);
+ void VerifyFunctionMetadata(
+ const SmallVector<std::pair<unsigned, MDNode *>, 4> MDs);
void VerifyConstantExprBitcastType(const ConstantExpr *CE);
void VerifyStatepoint(ImmutableCallSite CS);
if (GV.hasAppendingLinkage()) {
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV);
- Assert(GVar && GVar->getType()->getElementType()->isArrayTy(),
+ Assert(GVar && GVar->getValueType()->isArrayTy(),
"Only global arrays can have appending linkage!", GVar);
}
}
"invalid linkage for intrinsic global variable", &GV);
// Don't worry about emitting an error for it not being an array,
// visitGlobalValue will complain on appending non-array.
- if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getType()->getElementType())) {
+ if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getValueType())) {
StructType *STy = dyn_cast<StructType>(ATy->getElementType());
PointerType *FuncPtrTy =
FunctionType::get(Type::getVoidTy(*Context), false)->getPointerTo();
GV.getName() == "llvm.compiler.used")) {
Assert(!GV.hasInitializer() || GV.hasAppendingLinkage(),
"invalid linkage for intrinsic global variable", &GV);
- Type *GVType = GV.getType()->getElementType();
+ Type *GVType = GV.getValueType();
if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) {
PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
Assert(PTy, "wrong type for intrinsic global variable", &GV);
I->getKindAsEnum() == Attribute::NoBuiltin ||
I->getKindAsEnum() == Attribute::Cold ||
I->getKindAsEnum() == Attribute::OptimizeNone ||
- I->getKindAsEnum() == Attribute::JumpTable) {
+ I->getKindAsEnum() == Attribute::JumpTable ||
+ I->getKindAsEnum() == Attribute::Convergent) {
if (!isFunction) {
CheckFailed("Attribute '" + I->getAsString() +
"' only applies to functions!", V);
V);
Assert(!AttrBuilder(Attrs, Idx)
- .hasAttributes(AttributeFuncs::typeIncompatible(Ty, Idx), Idx),
+ .overlaps(AttributeFuncs::typeIncompatible(Ty)),
"Wrong types for attribute: " +
- AttributeFuncs::typeIncompatible(Ty, Idx).getAsString(Idx),
+ AttributeSet::get(*Context, Idx,
+ AttributeFuncs::typeIncompatible(Ty)).getAsString(Idx),
V);
if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
}
}
+void Verifier::VerifyFunctionMetadata(
+ const SmallVector<std::pair<unsigned, MDNode *>, 4> MDs) {
+ if (MDs.empty())
+ return;
+
+ for (unsigned i = 0; i < MDs.size(); i++) {
+ if (MDs[i].first == LLVMContext::MD_prof) {
+ MDNode *MD = MDs[i].second;
+ Assert(MD->getNumOperands() == 2,
+ "!prof annotations should have exactly 2 operands", MD);
+
+ // Check first operand.
+ Assert(MD->getOperand(0) != nullptr, "first operand should not be null",
+ MD);
+ Assert(isa<MDString>(MD->getOperand(0)),
+ "expected string with name of the !prof annotation", MD);
+ MDString *MDS = cast<MDString>(MD->getOperand(0));
+ StringRef ProfName = MDS->getString();
+ Assert(ProfName.equals("function_entry_count"),
+ "first operand should be 'function_entry_count'", MD);
+
+ // Check second operand.
+ Assert(MD->getOperand(1) != nullptr, "second operand should not be null",
+ MD);
+ Assert(isa<ConstantAsMetadata>(MD->getOperand(1)),
+ "expected integer argument to function_entry_count", MD);
+ }
+ }
+}
+
void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) {
if (CE->getOpcode() != Instruction::BitCast)
return;
"reordering restrictions required by safepoint semantics",
&CI);
- const Value *Target = CS.getArgument(0);
+ const Value *IDV = CS.getArgument(0);
+ Assert(isa<ConstantInt>(IDV), "gc.statepoint ID must be a constant integer",
+ &CI);
+
+ const Value *NumPatchBytesV = CS.getArgument(1);
+ Assert(isa<ConstantInt>(NumPatchBytesV),
+ "gc.statepoint number of patchable bytes must be a constant integer",
+ &CI);
+ const int64_t NumPatchBytes =
+ cast<ConstantInt>(NumPatchBytesV)->getSExtValue();
+ assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!");
+ Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be "
+ "positive",
+ &CI);
+
+ const Value *Target = CS.getArgument(2);
const PointerType *PT = dyn_cast<PointerType>(Target->getType());
Assert(PT && PT->getElementType()->isFunctionTy(),
"gc.statepoint callee must be of function pointer type", &CI, Target);
FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
- const Value *NumCallArgsV = CS.getArgument(1);
+ if (NumPatchBytes)
+ Assert(isa<ConstantPointerNull>(Target->stripPointerCasts()),
+ "gc.statepoint must have null as call target if number of patchable "
+ "bytes is non zero",
+ &CI);
+
+ const Value *NumCallArgsV = CS.getArgument(3);
Assert(isa<ConstantInt>(NumCallArgsV),
"gc.statepoint number of arguments to underlying call "
"must be constant integer",
Assert(NumCallArgs == NumParams,
"gc.statepoint mismatch in number of call args", &CI);
- const Value *Unused = CS.getArgument(2);
- Assert(isa<ConstantInt>(Unused) && cast<ConstantInt>(Unused)->isNullValue(),
- "gc.statepoint parameter #3 must be zero", &CI);
+ const Value *FlagsV = CS.getArgument(4);
+ Assert(isa<ConstantInt>(FlagsV),
+ "gc.statepoint flags must be constant integer", &CI);
+ const uint64_t Flags = cast<ConstantInt>(FlagsV)->getZExtValue();
+ Assert((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0,
+ "unknown flag used in gc.statepoint flags argument", &CI);
// Verify that the types of the call parameter arguments match
// the type of the wrapped callee.
for (int i = 0; i < NumParams; i++) {
Type *ParamType = TargetFuncType->getParamType(i);
- Type *ArgType = CS.getArgument(3+i)->getType();
+ Type *ArgType = CS.getArgument(5 + i)->getType();
Assert(ArgType == ParamType,
"gc.statepoint call argument does not match wrapped "
"function type",
&CI);
}
- const int EndCallArgsInx = 2+NumCallArgs;
- const Value *NumDeoptArgsV = CS.getArgument(EndCallArgsInx+1);
+
+ const int EndCallArgsInx = 4 + NumCallArgs;
+
+ const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1);
+ Assert(isa<ConstantInt>(NumTransitionArgsV),
+ "gc.statepoint number of transition arguments "
+ "must be constant integer",
+ &CI);
+ const int NumTransitionArgs =
+ cast<ConstantInt>(NumTransitionArgsV)->getZExtValue();
+ Assert(NumTransitionArgs >= 0,
+ "gc.statepoint number of transition arguments must be positive", &CI);
+ const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs;
+
+ const Value *NumDeoptArgsV = CS.getArgument(EndTransitionArgsInx+1);
Assert(isa<ConstantInt>(NumDeoptArgsV),
"gc.statepoint number of deoptimization arguments "
"must be constant integer",
"must be positive",
&CI);
- Assert(4 + NumCallArgs + NumDeoptArgs <= (int)CS.arg_size(),
+ const int ExpectedNumArgs =
+ 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
+ Assert(ExpectedNumArgs <= (int)CS.arg_size(),
"gc.statepoint too few arguments according to length fields", &CI);
// Check that the only uses of this gc.statepoint are gc.result or
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
assert(F.hasMetadata() != MDs.empty() && "Bit out-of-sync");
+ VerifyFunctionMetadata(MDs);
if (F.isMaterializable()) {
// Function has a body somewhere we can't see.
// Check that all of the values of the PHI node have the same type as the
// result, and that the incoming blocks are really basic blocks.
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
- Assert(PN.getType() == PN.getIncomingValue(i)->getType(),
+ for (Value *IncValue : PN.incoming_values()) {
+ Assert(PN.getType() == IncValue->getType(),
"PHI node operands are not the same type as the result!", &PN);
}
verifyMustTailCall(CI);
if (Function *F = CI.getCalledFunction())
- if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
+ if (Intrinsic::ID ID = F->getIntrinsicID())
visitIntrinsicFunctionCall(ID, CI);
}
dyn_cast<PointerType>(ThisArgVecTy->getVectorElementType());
if (!ThisArgEltTy)
return true;
- return (!(ThisArgEltTy->getElementType() ==
- ReferenceType->getVectorElementType()));
+ return ThisArgEltTy->getElementType() !=
+ ReferenceType->getVectorElementType();
}
}
llvm_unreachable("unhandled");
Assert(AI, "llvm.gcroot parameter #1 must be an alloca.", &CI);
Assert(isa<Constant>(CI.getArgOperand(1)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
- if (!AI->getType()->getElementType()->isPointerTy()) {
+ if (!AI->getAllocatedType()->isPointerTy()) {
Assert(!isa<ConstantPointerNull>(CI.getArgOperand(1)),
"llvm.gcroot parameter #1 must either be a pointer alloca, "
"or argument #2 must be a non-null constant.",
CI.getArgOperand(0));
// Assert that result type matches wrapped callee.
- const Value *Target = StatepointCS.getArgument(0);
+ const Value *Target = StatepointCS.getArgument(2);
const PointerType *PT = cast<PointerType>(Target->getType());
const FunctionType *TargetFuncType =
cast<FunctionType>(PT->getElementType());
"gc relocate on unwind path incorrectly linked to the statepoint",
&CI);
- const BasicBlock *invokeBB =
+ const BasicBlock *InvokeBB =
ExtractValue->getParent()->getUniquePredecessor();
// Landingpad relocates should have only one predecessor with invoke
// statepoint terminator
- Assert(invokeBB, "safepoints should have unique landingpads",
+ Assert(InvokeBB, "safepoints should have unique landingpads",
ExtractValue->getParent());
- Assert(invokeBB->getTerminator(), "safepoint block should be well formed",
- invokeBB);
- Assert(isStatepoint(invokeBB->getTerminator()),
- "gc relocate should be linked to a statepoint", invokeBB);
+ Assert(InvokeBB->getTerminator(), "safepoint block should be well formed",
+ InvokeBB);
+ Assert(isStatepoint(InvokeBB->getTerminator()),
+ "gc relocate should be linked to a statepoint", InvokeBB);
}
else {
// In all other cases relocate should be tied to the statepoint directly.
// Verify rest of the relocate arguments
- GCRelocateOperands ops(&CI);
- ImmutableCallSite StatepointCS(ops.statepoint());
+ GCRelocateOperands Ops(&CI);
+ ImmutableCallSite StatepointCS(Ops.getStatepoint());
// Both the base and derived must be piped through the safepoint
Value* Base = CI.getArgOperand(1);
// section of the statepoint's argument
Assert(StatepointCS.arg_size() > 0,
"gc.statepoint: insufficient arguments");
- Assert(isa<ConstantInt>(StatepointCS.getArgument(1)),
+ Assert(isa<ConstantInt>(StatepointCS.getArgument(3)),
"gc.statement: number of call arguments must be constant integer");
const unsigned NumCallArgs =
- cast<ConstantInt>(StatepointCS.getArgument(1))->getZExtValue();
- Assert(StatepointCS.arg_size() > NumCallArgs+3,
+ cast<ConstantInt>(StatepointCS.getArgument(3))->getZExtValue();
+ Assert(StatepointCS.arg_size() > NumCallArgs + 5,
"gc.statepoint: mismatch in number of call arguments");
- Assert(isa<ConstantInt>(StatepointCS.getArgument(NumCallArgs+3)),
+ Assert(isa<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 5)),
+ "gc.statepoint: number of transition arguments must be "
+ "a constant integer");
+ const int NumTransitionArgs =
+ cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 5))
+ ->getZExtValue();
+ const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1;
+ Assert(isa<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart)),
"gc.statepoint: number of deoptimization arguments must be "
"a constant integer");
const int NumDeoptArgs =
- cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
- const int GCParamArgsStart = NumCallArgs + NumDeoptArgs + 4;
+ cast<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart))->getZExtValue();
+ const int GCParamArgsStart = DeoptArgsStart + 1 + NumDeoptArgs;
const int GCParamArgsEnd = StatepointCS.arg_size();
Assert(GCParamArgsStart <= BaseIndex && BaseIndex < GCParamArgsEnd,
"gc.relocate: statepoint base index doesn't fall within the "
"'gc parameters' section of the statepoint call",
&CI);
- // Assert that the result type matches the type of the relocated pointer
+ // Relocated value must be a pointer type, but gc_relocate does not need to return the
+ // same pointer type as the relocated pointer. It can be casted to the correct type later
+ // if it's desired. However, they must have the same address space.
GCRelocateOperands Operands(&CI);
- Assert(Operands.derivedPtr()->getType() == CI.getType(),
- "gc.relocate: relocating a pointer shouldn't change its type", &CI);
+ Assert(Operands.getDerivedPtr()->getType()->isPointerTy(),
+ "gc.relocate: relocated value must be a gc pointer", &CI);
+
+ // gc_relocate return type must be a pointer type, and is verified earlier in
+ // VerifyIntrinsicType().
+ Assert(cast<PointerType>(CI.getType())->getAddressSpace() ==
+ cast<PointerType>(Operands.getDerivedPtr()->getType())->getAddressSpace(),
+ "gc.relocate: relocating a pointer shouldn't change its address space", &CI);
break;
}
};
if (!E->isBitPiece())
return;
+ // The frontend helps out GDB by emitting the members of local anonymous
+ // unions as artificial local variables with shared storage. When SROA splits
+ // the storage for artificial local variables that are smaller than the entire
+ // union, the overhang piece will be outside of the allotted space for the
+ // variable and this check fails.
+ // FIXME: Remove this check as soon as clang stops doing this; it hides bugs.
+ if (V->isArtificial())
+ return;
+
// If there's no size, the type is broken, but that should be checked
// elsewhere.
uint64_t VarSize = getVariableSize(*V, TypeRefs);