summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/LangRef.rst20
-rw-r--r--llvm/include/llvm-c/Core.h3
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h4
-rw-r--r--llvm/include/llvm/IR/Type.h17
-rw-r--r--llvm/lib/Analysis/CodeMetrics.cpp3
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp2
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp3
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/IR/AsmWriter.cpp1
-rw-r--r--llvm/lib/IR/Core.cpp5
-rw-r--r--llvm/lib/IR/Instructions.cpp5
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp1
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h2
-rw-r--r--llvm/lib/IR/Type.cpp10
-rw-r--r--llvm/lib/IR/Verifier.cpp25
-rw-r--r--llvm/lib/Target/CppBackend/CPPBackend.cpp3
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp1
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp5
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp8
-rw-r--r--llvm/test/Assembler/token.ll6
-rw-r--r--llvm/test/Bitcode/compatibility.ll3
-rw-r--r--llvm/test/Verifier/token1.ll11
-rw-r--r--llvm/test/Verifier/token2.ll11
-rw-r--r--llvm/test/Verifier/token3.ll8
-rw-r--r--llvm/test/Verifier/token4.ll4
-rw-r--r--llvm/test/Verifier/token5.ll7
-rw-r--r--llvm/test/Verifier/token6.ll7
-rw-r--r--llvm/test/Verifier/token7.ll8
29 files changed, 160 insertions, 25 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 38e8fe2b201..ef5913b78f3 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2168,6 +2168,26 @@ The label type represents code labels.
label
+.. _t_token:
+
+Token Type
+^^^^^^^^^^
+
+:Overview:
+
+The token type is used when a value is associated with an instruction
+but all uses of the value must not attempt to introspect or obscure it.
+As such, it is not appropriate to have a :ref:`phi <i_phi>` or
+:ref:`select <i_select>` of type token.
+
+:Syntax:
+
+::
+
+ token
+
+
+
.. _t_metadata:
Metadata Type
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index ac0b10a6ff6..3bb8828fe84 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -274,7 +274,8 @@ typedef enum {
LLVMPointerTypeKind, /**< Pointers */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
LLVMMetadataTypeKind, /**< Metadata */
- LLVMX86_MMXTypeKind /**< X86 MMX */
+ LLVMX86_MMXTypeKind, /**< X86 MMX */
+ LLVMTokenTypeKind /**< Tokens */
} LLVMTypeKind;
typedef enum {
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 6a9f32e1aad..a8302e230f3 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -121,7 +121,9 @@ namespace bitc {
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
- TYPE_CODE_FUNCTION = 21 // FUNCTION: [vararg, retty, paramty x N]
+ TYPE_CODE_FUNCTION = 21, // FUNCTION: [vararg, retty, paramty x N]
+
+ TYPE_CODE_TOKEN = 22 // TOKEN
};
// The type symbol table only has one code (TST_ENTRY_CODE).
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 28dafeba4bc..adfa5f25a22 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -63,15 +63,16 @@ public:
LabelTyID, ///< 7: Labels
MetadataTyID, ///< 8: Metadata
X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific)
+ TokenTyID, ///< 10: Tokens
// Derived types... see DerivedTypes.h file.
// Make sure FirstDerivedTyID stays up to date!
- IntegerTyID, ///< 10: Arbitrary bit width integers
- FunctionTyID, ///< 11: Functions
- StructTyID, ///< 12: Structures
- ArrayTyID, ///< 13: Arrays
- PointerTyID, ///< 14: Pointers
- VectorTyID ///< 15: SIMD 'packed' format, or other vector type
+ IntegerTyID, ///< 11: Arbitrary bit width integers
+ FunctionTyID, ///< 12: Functions
+ StructTyID, ///< 13: Structures
+ ArrayTyID, ///< 14: Arrays
+ PointerTyID, ///< 15: Pointers
+ VectorTyID ///< 16: SIMD 'packed' format, or other vector type
};
private:
@@ -178,6 +179,9 @@ public:
/// isMetadataTy - Return true if this is 'metadata'.
bool isMetadataTy() const { return getTypeID() == MetadataTyID; }
+ /// isTokenTy - Return true if this is 'token'.
+ bool isTokenTy() const { return getTypeID() == TokenTyID; }
+
/// isIntegerTy - True if this is an instance of IntegerType.
///
bool isIntegerTy() const { return getTypeID() == IntegerTyID; }
@@ -378,6 +382,7 @@ public:
static Type *getFP128Ty(LLVMContext &C);
static Type *getPPC_FP128Ty(LLVMContext &C);
static Type *getX86_MMXTy(LLVMContext &C);
+ static Type *getTokenTy(LLVMContext &C);
static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
static IntegerType *getInt1Ty(LLVMContext &C);
static IntegerType *getInt8Ty(LLVMContext &C);
diff --git a/llvm/lib/Analysis/CodeMetrics.cpp b/llvm/lib/Analysis/CodeMetrics.cpp
index 46a2c43b169..157a4bdd11c 100644
--- a/llvm/lib/Analysis/CodeMetrics.cpp
+++ b/llvm/lib/Analysis/CodeMetrics.cpp
@@ -155,6 +155,9 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB,
if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy())
++NumVectorInsts;
+ if (II->getType()->isTokenTy() && II->isUsedOutsideOfBlock(BB))
+ notDuplicatable = true;
+
if (const CallInst *CI = dyn_cast<CallInst>(II))
if (CI->cannotDuplicate())
notDuplicatable = true;
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 1ad4fd893bc..3d30c3a06e2 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -220,6 +220,8 @@ bool Loop::isSafeToClone() const {
if (CI->cannotDuplicate())
return false;
}
+ if (BI->getType()->isTokenTy() && BI->isUsedOutsideOfBlock(*I))
+ return false;
}
}
return true;
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index be951f5c7d8..6d62584577a 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -691,6 +691,7 @@ lltok::Kind LLLexer::LexIdentifier() {
TYPEKEYWORD("label", Type::getLabelTy(Context));
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
+ TYPEKEYWORD("token", Type::getTokenTy(Context));
#undef TYPEKEYWORD
// Keywords for instructions.
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 658c08f3646..06935f7ab1b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1360,6 +1360,9 @@ std::error_code BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_X86_MMX: // X86_MMX
ResultTy = Type::getX86_MMXTy(Context);
break;
+ case bitc::TYPE_CODE_TOKEN: // TOKEN
+ ResultTy = Type::getTokenTy(Context);
+ break;
case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width]
if (Record.size() < 1)
return error("Invalid record");
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 0d1a2accc4f..03650ec37b7 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -405,6 +405,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
+ case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break;
case Type::IntegerTyID:
// INTEGER: [width]
Code = bitc::TYPE_CODE_INTEGER;
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 76b3b3103c1..9ce384825f4 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -467,6 +467,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
+ case Type::TokenTyID: OS << "token"; return;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
return;
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index a3768485fd5..2937a62f3b5 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -262,6 +262,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMVectorTypeKind;
case Type::X86_MMXTyID:
return LLVMX86_MMXTypeKind;
+ case Type::TokenTyID:
+ return LLVMTokenTypeKind;
}
llvm_unreachable("Unhandled TypeID.");
}
@@ -366,6 +368,9 @@ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) {
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) {
return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C));
}
+LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C) {
+ return (LLVMTypeRef) Type::getTokenTy(*unwrap(C));
+}
LLVMTypeRef LLVMHalfType(void) {
return LLVMHalfTypeInContext(LLVMGetGlobalContext());
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 18f2f1385f4..79fb30e4734 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -62,7 +62,10 @@ UnaryInstruction::~UnaryInstruction() {
const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
if (Op1->getType() != Op2->getType())
return "both values to select must have same type";
-
+
+ if (Op1->getType()->isTokenTy())
+ return "select values cannot have token type";
+
if (VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
// Vector select.
if (VT->getElementType() != Type::getInt1Ty(Op0->getContext()))
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 0ce28712339..dc367fee884 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -27,6 +27,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
FloatTy(C, Type::FloatTyID),
DoubleTy(C, Type::DoubleTyID),
MetadataTy(C, Type::MetadataTyID),
+ TokenTy(C, Type::TokenTyID),
X86_FP80Ty(C, Type::X86_FP80TyID),
FP128Ty(C, Type::FP128TyID),
PPC_FP128Ty(C, Type::PPC_FP128TyID),
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index f514beabd0d..cf0aa5c62ab 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -928,7 +928,7 @@ public:
ConstantInt *TheFalseVal;
// Basic type instances.
- Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;
+ Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy, TokenTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;
IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index fbcd887ec68..c3c3f492b5b 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -35,6 +35,7 @@ Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
case LabelTyID : return getLabelTy(C);
case MetadataTyID : return getMetadataTy(C);
case X86_MMXTyID : return getX86_MMXTy(C);
+ case TokenTyID : return getTokenTy(C);
default:
return nullptr;
}
@@ -220,6 +221,7 @@ Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; }
Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; }
Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; }
Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; }
+Type *Type::getTokenTy(LLVMContext &C) { return &C.pImpl->TokenTy; }
Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; }
Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; }
Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; }
@@ -595,7 +597,8 @@ void StructType::setBody(Type *type, ...) {
bool StructType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
+ !ElemTy->isTokenTy();
}
/// isLayoutIdentical - Return true if this is layout identical to the
@@ -690,7 +693,8 @@ ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) {
bool ArrayType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
+ !ElemTy->isTokenTy();
}
//===----------------------------------------------------------------------===//
@@ -758,7 +762,7 @@ PointerType *Type::getPointerTo(unsigned addrs) const {
bool PointerType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
- !ElemTy->isMetadataTy();
+ !ElemTy->isMetadataTy() && !ElemTy->isTokenTy();
}
bool PointerType::isLoadableOrStorableType(Type *ElemTy) {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 863ddc7e2dd..af1121e3c73 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1739,11 +1739,18 @@ void Verifier::visitFunction(const Function &F) {
FT->getParamType(i));
Assert(I->getType()->isFirstClassType(),
"Function arguments must have first-class types!", I);
- if (!isLLVMdotName)
+ if (!isLLVMdotName) {
Assert(!I->getType()->isMetadataTy(),
"Function takes metadata but isn't an intrinsic", I, &F);
+ Assert(!I->getType()->isTokenTy(),
+ "Function takes token but isn't an intrinsic", I, &F);
+ }
}
+ if (!isLLVMdotName)
+ Assert(!F.getReturnType()->isTokenTy(),
+ "Functions returns a token but isn't an intrinsic", &F);
+
// Get the function metadata attachments.
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
@@ -2190,6 +2197,9 @@ void Verifier::visitPHINode(PHINode &PN) {
isa<PHINode>(--BasicBlock::iterator(&PN)),
"PHI nodes not grouped at top of basic block!", &PN, PN.getParent());
+ // Check that a PHI doesn't yield a Token.
+ Assert(!PN.getType()->isTokenTy(), "PHI nodes cannot have token type!");
+
// 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 (Value *IncValue : PN.incoming_values()) {
@@ -2292,12 +2302,19 @@ void Verifier::VerifyCallSite(CallSite CS) {
// Verify that there's no metadata unless it's a direct call to an intrinsic.
if (CS.getCalledFunction() == nullptr ||
!CS.getCalledFunction()->getName().startswith("llvm.")) {
- for (FunctionType::param_iterator PI = FTy->param_begin(),
- PE = FTy->param_end(); PI != PE; ++PI)
- Assert(!(*PI)->isMetadataTy(),
+ for (Type *ParamTy : FTy->params()) {
+ Assert(!ParamTy->isMetadataTy(),
"Function has metadata parameter but isn't an intrinsic", I);
+ Assert(!ParamTy->isTokenTy(),
+ "Function has token parameter but isn't an intrinsic", I);
+ }
}
+ // Verify that indirect calls don't return tokens.
+ if (CS.getCalledFunction() == nullptr)
+ Assert(!FTy->getReturnType()->isTokenTy(),
+ "Return type cannot be token for indirect call!");
+
if (Function *F = CS.getCalledFunction())
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCallSite(ID, CS);
diff --git a/llvm/lib/Target/CppBackend/CPPBackend.cpp b/llvm/lib/Target/CppBackend/CPPBackend.cpp
index 272688edb8a..d9d2de42f3e 100644
--- a/llvm/lib/Target/CppBackend/CPPBackend.cpp
+++ b/llvm/lib/Target/CppBackend/CPPBackend.cpp
@@ -551,7 +551,8 @@ void CppWriter::printAttributes(const AttributeSet &PAL,
void CppWriter::printType(Type* Ty) {
// We don't print definitions for primitive types
if (Ty->isFloatingPointTy() || Ty->isX86_MMXTy() || Ty->isIntegerTy() ||
- Ty->isLabelTy() || Ty->isMetadataTy() || Ty->isVoidTy())
+ Ty->isLabelTy() || Ty->isMetadataTy() || Ty->isVoidTy() ||
+ Ty->isTokenTy())
return;
// If we already defined this type, we don't need to define it again.
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index dba2d1bee60..13cdef90106 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -654,6 +654,7 @@ int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
case Type::PPC_FP128TyID:
case Type::LabelTyID:
case Type::MetadataTyID:
+ case Type::TokenTyID:
return 0;
case Type::PointerTyID: {
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 6ad782f5089..b87f4766e8d 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -260,6 +260,11 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB,
if (isa<BitCastInst>(I) && I->getType()->isPointerTy())
continue;
+ // Bail out if this instruction gives back a token type, it is not possible
+ // to duplicate it if it used outside this BB.
+ if (I->getType()->isTokenTy() && I->isUsedOutsideOfBlock(BB))
+ return ~0U;
+
// All other instructions count for at least one unit.
++Size;
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index a7515bbf961..83dd1826c22 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -337,14 +337,8 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
TPI->eraseFromParent();
UpdatePHINodes(BB);
}
- } else if (auto *CPI = dyn_cast<CleanupPadInst>(I)) {
- if (CPI->getNumOperands() == 0) {
- CleanupPadInst::Create(CPI->getType(), {UnwindDest}, CPI->getName(),
- CPI);
- CPI->eraseFromParent();
- }
} else {
- assert(isa<CatchPadInst>(I));
+ assert(isa<CatchPadInst>(I) || isa<CleanupPadInst>(I));
}
}
diff --git a/llvm/test/Assembler/token.ll b/llvm/test/Assembler/token.ll
new file mode 100644
index 00000000000..22d71b0b730
--- /dev/null
+++ b/llvm/test/Assembler/token.ll
@@ -0,0 +1,6 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+; Basic smoke test for token type.
+
+; CHECK: declare void @llvm.token.foobar(token)
+declare void @llvm.token.foobar(token)
diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll
index 585d51b73d4..8763fd4cad1 100644
--- a/llvm/test/Bitcode/compatibility.ll
+++ b/llvm/test/Bitcode/compatibility.ll
@@ -1212,6 +1212,9 @@ define void @misc.metadata() {
ret void
}
+declare void @llvm.tokenfoo(token)
+; CHECK: declare void @llvm.tokenfoo(token)
+
; CHECK: attributes #0 = { alignstack=4 }
; CHECK: attributes #1 = { alignstack=8 }
; CHECK: attributes #2 = { alwaysinline }
diff --git a/llvm/test/Verifier/token1.ll b/llvm/test/Verifier/token1.ll
new file mode 100644
index 00000000000..ac7ff30948e
--- /dev/null
+++ b/llvm/test/Verifier/token1.ll
@@ -0,0 +1,11 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f(token %A, token %B) {
+entry:
+ br label %bb
+
+bb:
+ %phi = phi token [ %A, %bb ], [ %B, %entry]
+; CHECK: PHI nodes cannot have token type!
+ br label %bb
+}
diff --git a/llvm/test/Verifier/token2.ll b/llvm/test/Verifier/token2.ll
new file mode 100644
index 00000000000..b58079de770
--- /dev/null
+++ b/llvm/test/Verifier/token2.ll
@@ -0,0 +1,11 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f(token %A, token %B) {
+entry:
+ br label %bb
+
+bb:
+ %sel = select i1 undef, token %A, token %B
+; CHECK: select values cannot have token type
+ br label %bb
+}
diff --git a/llvm/test/Verifier/token3.ll b/llvm/test/Verifier/token3.ll
new file mode 100644
index 00000000000..2cce6b83e7f
--- /dev/null
+++ b/llvm/test/Verifier/token3.ll
@@ -0,0 +1,8 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f(token %A, token %B) {
+entry:
+ alloca token
+; CHECK: invalid type for alloca
+ ret void
+}
diff --git a/llvm/test/Verifier/token4.ll b/llvm/test/Verifier/token4.ll
new file mode 100644
index 00000000000..87a8b14efa0
--- /dev/null
+++ b/llvm/test/Verifier/token4.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+@GV = external global token
+; CHECK: invalid type for global variable
diff --git a/llvm/test/Verifier/token5.ll b/llvm/test/Verifier/token5.ll
new file mode 100644
index 00000000000..6fc1b045375
--- /dev/null
+++ b/llvm/test/Verifier/token5.ll
@@ -0,0 +1,7 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f(token %A) {
+entry:
+ ret void
+}
+; CHECK: Function takes token but isn't an intrinsic
diff --git a/llvm/test/Verifier/token6.ll b/llvm/test/Verifier/token6.ll
new file mode 100644
index 00000000000..9614b91db73
--- /dev/null
+++ b/llvm/test/Verifier/token6.ll
@@ -0,0 +1,7 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define token @f() {
+entry:
+ ret token undef
+}
+; CHECK: Functions returns a token but isn't an intrinsic
diff --git a/llvm/test/Verifier/token7.ll b/llvm/test/Verifier/token7.ll
new file mode 100644
index 00000000000..939878cc427
--- /dev/null
+++ b/llvm/test/Verifier/token7.ll
@@ -0,0 +1,8 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @f() {
+entry:
+ call token () undef ()
+ ret void
+}
+; CHECK: Return type cannot be token for indirect call!
OpenPOWER on IntegriCloud