void-packages/srcpkgs/ispc/patches/llvm12-005.patch
2021-05-18 02:12:15 +02:00

372 lines
20 KiB
Diff

From c1d0a51bf8416d42144de9e2bdd59825eaeff1ac Mon Sep 17 00:00:00 2001
From: Arina Neshlyaeva <arina.neshlyaeva@intel.com>
Date: Fri, 8 Jan 2021 14:13:49 -0800
Subject: [PATCH] LLVM 11 support for gen code
---
src/ctx.cpp | 13 ++-
src/gen/GlobalsLocalization.cpp | 9 +-
src/opt.cpp | 143 ++++++++++++++++++++++++--------
3 files changed, 124 insertions(+), 41 deletions(-)
diff --git a/src/ctx.cpp b/src/ctx.cpp
index b60e6fe84..2a72e6837 100644
--- a/src/ctx.cpp
+++ b/src/ctx.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2010-2020, Intel Corporation
+ Copyright (c) 2010-2021, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -3685,8 +3685,17 @@ llvm::Value *FunctionEmitContext::GenXSimdCFPredicate(llvm::Value *value, llvm::
AssertPos(currentPos, llvm::isa<llvm::VectorType>(value->getType()));
llvm::VectorType *vt = llvm::dyn_cast<llvm::VectorType>(value->getType());
if (defaults == NULL) {
- defaults = llvm::ConstantVector::getSplat(value->getType()->getVectorNumElements(),
+#if ISPC_LLVM_VERSION < ISPC_LLVM_11_0
+ defaults = llvm::ConstantVector::getSplat(vt->getVectorNumElements(),
+ llvm::Constant::getNullValue(vt->getElementType()));
+#elif ISPC_LLVM_VERSION == ISPC_LLVM_11_0
+ defaults = llvm::ConstantVector::getSplat({static_cast<unsigned int>(vt->getNumElements()), false},
llvm::Constant::getNullValue(vt->getElementType()));
+#else
+ defaults = llvm::ConstantVector::getSplat(
+ llvm::ElementCount::get(static_cast<unsigned int>(vt->getNumElements()), false),
+ llvm::Constant::getNullValue(vt->getElementType()));
+#endif
}
auto Fn = llvm::GenXIntrinsic::getGenXDeclaration(m->module, llvm::GenXIntrinsic::genx_simdcf_predicate,
diff --git a/src/gen/GlobalsLocalization.cpp b/src/gen/GlobalsLocalization.cpp
index a176e9462..41f3b00e2 100644
--- a/src/gen/GlobalsLocalization.cpp
+++ b/src/gen/GlobalsLocalization.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2014, 2016-2020, Intel Corporation
+ Copyright (c) 2014, 2016-2021, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -53,8 +53,10 @@
#include <llvm/GenXIntrinsics/GenXIntrOpts.h>
#include <llvm/GenXIntrinsics/GenXIntrinsics.h>
#include <llvm/GenXIntrinsics/GenXMetadata.h>
-#include <llvm/IR/CFG.h>
+#if ISPC_LLVM_VERSION < ISPC_LLVM_11_0
#include <llvm/IR/CallSite.h>
+#endif
+#include <llvm/IR/CFG.h>
#include <llvm/IR/DebugInfo.h>
#include <llvm/IR/Dominators.h>
#include <llvm/IR/Function.h>
@@ -470,7 +472,8 @@ void GlobalsLocalization::LocalizeGlobals(LocalizationInfo &LI) {
Instruction &FirstI = *Fn->getEntryBlock().begin();
Type *ElemTy = GV->getType()->getElementType();
AllocaInst *Alloca = new AllocaInst(ElemTy, 0, GV->getName() + ".local", &FirstI);
- Alloca->setAlignment(llvm::MaybeAlign(GV->getAlignment()));
+ Alloca->setAlignment(llvm::MaybeAlign(GV->getAlignment()).valueOrOne());
+
if (!isa<UndefValue>(GV->getInitializer()))
new StoreInst(GV->getInitializer(), Alloca, &FirstI);
diff --git a/src/opt.cpp b/src/opt.cpp
index d58d77f73..1789b8476 100644
--- a/src/opt.cpp
+++ b/src/opt.cpp
@@ -2899,15 +2899,17 @@ static llvm::Function *lGenXMaskedInt8Inst(llvm::Instruction *inst, bool isStore
static llvm::CallInst *lGenXStoreInst(llvm::Value *val, llvm::Value *ptr, llvm::Instruction *inst) {
Assert(g->target->isGenXTarget());
Assert(llvm::isa<llvm::VectorType>(val->getType()));
- Assert(llvm::isPowerOf2_32(val->getType()->getVectorNumElements()));
- Assert(val->getType()->getPrimitiveSizeInBits() / 8 <= 8 * OWORD);
+
+ llvm::VectorType *valVecType = llvm::dyn_cast<llvm::VectorType>(val->getType());
+ Assert(llvm::isPowerOf2_32(valVecType->getNumElements()));
+ Assert(valVecType->getPrimitiveSizeInBits() / 8 <= 8 * OWORD);
// The data write of svm store must have a size that is a power of two from 16 to 128
// bytes. However for int8 type and simd width = 8, the data write size is 8.
// So we use masked store function here instead of svm store which process int8 type
// correctly.
- if (val->getType()->getPrimitiveSizeInBits() / 8 < 16) {
- Assert(val->getType()->getScalarType() == LLVMTypes::Int8Type);
+ if (valVecType->getPrimitiveSizeInBits() / 8 < 16) {
+ Assert(valVecType->getScalarType() == LLVMTypes::Int8Type);
if (llvm::Function *maskedFunc = lGenXMaskedInt8Inst(inst, true))
return llvm::dyn_cast<llvm::CallInst>(lCallInst(maskedFunc, ptr, val, LLVMMaskAllOn, ""));
else {
@@ -2923,15 +2925,17 @@ static llvm::CallInst *lGenXStoreInst(llvm::Value *val, llvm::Value *ptr, llvm::
static llvm::CallInst *lGenXLoadInst(llvm::Value *ptr, llvm::Type *retType, llvm::Instruction *inst) {
Assert(llvm::isa<llvm::VectorType>(retType));
- Assert(llvm::isPowerOf2_32(retType->getVectorNumElements()));
- Assert(retType->getPrimitiveSizeInBits());
- Assert(retType->getPrimitiveSizeInBits() / 8 <= 8 * OWORD);
+
+ llvm::VectorType *retVecType = llvm::dyn_cast<llvm::VectorType>(retType);
+ Assert(llvm::isPowerOf2_32(retVecType->getNumElements()));
+ Assert(retVecType->getPrimitiveSizeInBits());
+ Assert(retVecType->getPrimitiveSizeInBits() / 8 <= 8 * OWORD);
// The data read of svm load must have a size that is a power of two from 16 to 128
// bytes. However for int8 type and simd width = 8, the data read size is 8.
// So we use masked load function here instead of svm load which process int8 type
// correctly.
- if (retType->getPrimitiveSizeInBits() / 8 < 16) {
- Assert(retType->getScalarType() == LLVMTypes::Int8Type);
+ if (retVecType->getPrimitiveSizeInBits() / 8 < 16) {
+ Assert(retVecType->getScalarType() == LLVMTypes::Int8Type);
if (llvm::Function *maskedFunc = lGenXMaskedInt8Inst(inst, false))
return llvm::dyn_cast<llvm::CallInst>(lCallInst(maskedFunc, ptr, LLVMMaskAllOn, ""));
else {
@@ -5622,15 +5626,24 @@ static bool lVectorizeGEPs(llvm::Value *ptr, std::vector<PtrUse> &ptrUses, std::
llvm::PtrToIntInst *ptrToInt =
new llvm::PtrToIntInst(ptr, LLVMTypes::Int64Type, "vectorized_ptrtoint", insertBefore);
llvm::Instruction *addr = llvm::BinaryOperator::CreateAdd(ptrToInt, offset, "vectorized_address", insertBefore);
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ llvm::Type *retType = llvm::FixedVectorType::get(scalar_type, reqSize / t_size);
+#else
llvm::Type *retType = llvm::VectorType::get(scalar_type, reqSize / t_size);
+#endif
llvm::Function *fn = llvm::GenXIntrinsic::getGenXDeclaration(
m->module, llvm::GenXIntrinsic::genx_svm_block_ld_unaligned, {retType, addr->getType()});
llvm::Instruction *ld = llvm::CallInst::Create(fn, {addr}, "vectorized_ld", insertBefore);
if (loadingPtr) {
// Cast int to ptr via inttoptr
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ ld = new llvm::IntToPtrInst(ld, llvm::FixedVectorType::get(originalType, reqSize / t_size),
+ "vectorized_inttoptr", insertBefore);
+#else
ld = new llvm::IntToPtrInst(ld, llvm::VectorType::get(originalType, reqSize / t_size),
"vectorized_inttoptr", insertBefore);
+#endif
}
// Scalar extracts for all loaded elements
@@ -6160,19 +6173,34 @@ bool ReplaceLLVMIntrinsics::runOnBasicBlock(llvm::BasicBlock &bb) {
llvm::Instruction *inst = &*I;
if (llvm::CallInst *ci = llvm::dyn_cast<llvm::CallInst>(inst)) {
llvm::Function *func = ci->getCalledFunction();
- if (func && func->getName() == "llvm.trap") {
+ if (func && func->getName().equals("llvm.trap")) {
llvm::Type *argTypes[] = {LLVMTypes::Int1VectorType, LLVMTypes::Int16VectorType};
// Description of parameters for genx_raw_send_noresult can be found in target-genx.ll
auto Fn = +llvm::GenXIntrinsic::getGenXDeclaration(
m->module, llvm::GenXIntrinsic::genx_raw_send_noresult, argTypes);
llvm::SmallVector<llvm::Value *, 8> Args;
Args.push_back(llvm::ConstantInt::get(LLVMTypes::Int32Type, 0));
- Args.push_back(llvm::ConstantVector::getSplat(g->target->getNativeVectorWidth(),
- llvm::ConstantInt::getTrue(*g->ctx)));
+ Args.push_back(llvm::ConstantVector::getSplat(
+#if ISPC_LLVM_VERSION < ISPC_LLVM_11_0
+ g->target->getNativeVectorWidth(),
+#elif ISPC_LLVM_VERSION == ISPC_LLVM_11_0
+ {static_cast<unsigned int>(g->target->getNativeVectorWidth()), false},
+#else // LLVM 12.0+
+ llvm::ElementCount::get(static_cast<unsigned int>(g->target->getNativeVectorWidth()), false),
+#endif
+ llvm::ConstantInt::getTrue(*g->ctx)));
+
Args.push_back(llvm::ConstantInt::get(LLVMTypes::Int32Type, 39));
Args.push_back(llvm::ConstantInt::get(LLVMTypes::Int32Type, 33554448));
llvm::Value *zeroMask = llvm::ConstantVector::getSplat(
- g->target->getNativeVectorWidth(), llvm::Constant::getNullValue(llvm::Type::getInt16Ty(*g->ctx)));
+#if ISPC_LLVM_VERSION < ISPC_LLVM_11_0
+ g->target->getNativeVectorWidth(),
+#elif ISPC_LLVM_VERSION == ISPC_LLVM_11_0
+ {static_cast<unsigned int>(g->target->getNativeVectorWidth()), false},
+#else // LLVM 12.0+
+ llvm::ElementCount::get(static_cast<unsigned int>(g->target->getNativeVectorWidth()), false),
+#endif
+ llvm::Constant::getNullValue(llvm::Type::getInt16Ty(*g->ctx)));
Args.push_back(zeroMask);
llvm::Instruction *newInst = llvm::CallInst::Create(Fn, Args, ci->getName());
@@ -6181,7 +6209,7 @@ bool ReplaceLLVMIntrinsics::runOnBasicBlock(llvm::BasicBlock &bb) {
modifiedAny = true;
goto restart;
}
- } else if (func && func->getName() == "llvm.assume") {
+ } else if (func && func->getName().equals("llvm.assume")) {
ci->eraseFromParent();
modifiedAny = true;
goto restart;
@@ -6335,7 +6363,7 @@ bool CheckUnsupportedInsts::runOnBasicBlock(llvm::BasicBlock &bb) {
continue;
for (int i = 0; i < unsupportedFuncs.size(); i++) {
std::smatch match;
- std::string funcName = func->getName();
+ std::string funcName = func->getName().str();
if (std::regex_match(funcName, match, unsupportedFuncs[i])) {
// We found unsupported function. Generate error and stop compilation.
SourcePos pos;
@@ -6418,12 +6446,14 @@ bool MangleOpenCLBuiltins::runOnBasicBlock(llvm::BasicBlock &bb) {
if (func->getName().startswith("__spirv_ocl")) {
std::string mangledName;
llvm::Type *retType = func->getReturnType();
- std::string funcName = func->getName();
+ std::string funcName = func->getName().str();
std::vector<llvm::Type *> ArgTy;
// spirv OpenCL builtins are used for double types only
- Assert(retType->isVectorTy() && retType->getVectorElementType()->isDoubleTy() ||
+ Assert(retType->isVectorTy() &&
+ llvm::dyn_cast<llvm::VectorType>(retType)->getElementType()->isDoubleTy() ||
retType->isSingleValueType() && retType->isDoubleTy());
- if (retType->isVectorTy() && retType->getVectorElementType()->isDoubleTy()) {
+ if (retType->isVectorTy() &&
+ llvm::dyn_cast<llvm::VectorType>(retType)->getElementType()->isDoubleTy()) {
ArgTy.push_back(LLVMTypes::DoubleVectorType);
// _DvWIDTH suffix is used in target file to differentiate scalar
// and vector versions of intrinsics. Here we remove this
@@ -6511,8 +6541,15 @@ llvm::Value *FixAddressSpace::calculateGatherScatterAddress(llvm::Value *Ptr, ll
// Cast offsets to int64
Offsets = new llvm::ZExtInst(
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ Offsets,
+ llvm::FixedVectorType::get(LLVMTypes::Int64Type,
+ llvm::dyn_cast<llvm::VectorType>(Offsets->getType())->getNumElements()),
+ "svm_offset_zext", InsertBefore);
+#else
Offsets, llvm::VectorType::get(LLVMTypes::Int64Type, Offsets->getType()->getVectorNumElements()),
"svm_offset_zext", InsertBefore);
+#endif
if (!llvm::isa<llvm::ConstantPointerNull>(Ptr)) {
// Cast ptr to int64
@@ -6520,13 +6557,31 @@ llvm::Value *FixAddressSpace::calculateGatherScatterAddress(llvm::Value *Ptr, ll
// Vectorize ptr
llvm::Value *undefInsertValue =
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ llvm::UndefValue::get(llvm::FixedVectorType::get(
+ LLVMTypes::Int64Type, llvm::dyn_cast<llvm::VectorType>(addressType)->getNumElements()));
+#else
llvm::UndefValue::get(llvm::VectorType::get(LLVMTypes::Int64Type, addressType->getVectorNumElements()));
+#endif
address = llvm::InsertElementInst::Create(undefInsertValue, address, LLVMInt32(0), "svm_ptr_iei", InsertBefore);
llvm::Constant *zeroVec = llvm::ConstantVector::getSplat(
+#if ISPC_LLVM_VERSION < ISPC_LLVM_11_0
addressType->getVectorNumElements(),
+#elif ISPC_LLVM_VERSION == ISPC_LLVM_11_0
+ {llvm::dyn_cast<llvm::VectorType>(addressType)->getNumElements(), false},
+#else
+ llvm::ElementCount::get(
+ llvm::dyn_cast<llvm::FixedVectorType>(addressType->getNumElements(), false),
+#endif
llvm::Constant::getNullValue(llvm::Type::getInt32Ty(InsertBefore->getContext())));
+
llvm::Value *undefShuffleValue =
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ llvm::UndefValue::get(llvm::FixedVectorType::get(
+ LLVMTypes::Int64Type, llvm::dyn_cast<llvm::VectorType>(addressType)->getNumElements()));
+#else
llvm::UndefValue::get(llvm::VectorType::get(LLVMTypes::Int64Type, addressType->getVectorNumElements()));
+#endif
address = new llvm::ShuffleVectorInst(address, undefShuffleValue, zeroVec, "svm_ptr_svi", InsertBefore);
// Calculate address
@@ -6553,9 +6608,12 @@ llvm::Instruction *FixAddressSpace::processVectorLoad(llvm::LoadInst *LI) {
if (retType->getScalarType()->isPointerTy()) {
isPtrLoad = true;
auto scalarType = g->target->is32Bit() ? LLVMTypes::Int32Type : LLVMTypes::Int64Type;
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ retType = llvm::FixedVectorType::get(scalarType, llvm::dyn_cast<llvm::VectorType>(retType)->getNumElements());
+#else
retType = llvm::VectorType::get(scalarType, retType->getVectorNumElements());
+#endif
}
-
llvm::Instruction *res = lGenXLoadInst(ptr, retType, llvm::dyn_cast<llvm::Instruction>(LI));
Assert(res);
@@ -6580,11 +6638,16 @@ llvm::Instruction *FixAddressSpace::processSVMVectorLoad(llvm::Instruction *CI)
ptr = new llvm::IntToPtrInst(ptr, llvm::PointerType::get(retType, 0), CI->getName() + "_inttoptr", CI);
llvm::Instruction *loadInst = NULL;
#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
- loadInst = new llvm::LoadInst(llvm::dyn_cast<llvm::PointerType>(ptr->getType())->getPointerElementType(), loadInst,
- CI->getName(), (llvm::Instruction *)NULL);
+ loadInst = new llvm::LoadInst(llvm::dyn_cast<llvm::PointerType>(ptr->getType())->getPointerElementType(), ptr,
+ CI->getName(), false /* not volatile */,
+ llvm::MaybeAlign(g->target->getNativeVectorAlignment()).valueOrOne(),
+ (llvm::Instruction *)NULL);
#else
- loadInst = new llvm::LoadInst(ptr, CI->getName(), (llvm::Instruction *)NULL);
+ loadInst = new llvm::LoadInst(ptr, CI->getName(), false,
+ llvm::MaybeAlign(g->target->getNativeVectorAlignment()).valueOrOne(),
+ (llvm::Instruction *)NULL);
#endif
+
Assert(loadInst);
return loadInst;
}
@@ -6606,7 +6669,11 @@ llvm::Instruction *FixAddressSpace::processVectorStore(llvm::StoreInst *SI) {
// Note: it doesn't look like a normal case for GenX target
if (valType->getScalarType()->isPointerTy()) {
auto scalarType = g->target->is32Bit() ? LLVMTypes::Int32Type : LLVMTypes::Int64Type;
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ valType = llvm::FixedVectorType::get(scalarType, llvm::dyn_cast<llvm::VectorType>(valType)->getNumElements());
+#else
valType = llvm::VectorType::get(scalarType, valType->getVectorNumElements());
+#endif
val = new llvm::PtrToIntInst(val, valType, "svm_st_val_ptrtoint", SI);
}
@@ -6631,12 +6698,8 @@ llvm::Instruction *FixAddressSpace::processSVMVectorStore(llvm::Instruction *CI)
ptr = new llvm::IntToPtrInst(ptr, llvm::PointerType::get(valType, 0), CI->getName() + "_inttoptr", CI);
llvm::Instruction *storeInst = NULL;
-#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
- loadInst = new llvm::StoreInst(val, llvm::dyn_cast<llvm::PointerType>(ptr->getType())->getPointerElementType(),
- storeInst, CI->getName(), (llvm::Instruction *)NULL);
-#else
- storeInst = new llvm::StoreInst(val, ptr, (llvm::Instruction *)NULL);
-#endif
+ storeInst = new llvm::StoreInst(val, ptr, (llvm::Instruction *)NULL,
+ llvm::MaybeAlign(g->target->getNativeVectorAlignment()).valueOrOne());
Assert(storeInst);
return storeInst;
}
@@ -6645,15 +6708,18 @@ llvm::Instruction *FixAddressSpace::createInt8WrRegion(llvm::Value *Val, llvm::V
int width = g->target->getVectorWidth();
llvm::Value *Args[8];
-
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ Args[0] = llvm::UndefValue::get(llvm::FixedVectorType::get(LLVMTypes::Int8Type, width * 4)); // old value
+#else
Args[0] = llvm::UndefValue::get(llvm::VectorType::get(LLVMTypes::Int8Type, width * 4)); // old value
- Args[1] = Val; // value to store
- Args[2] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 0); // vstride
- Args[3] = llvm::ConstantInt::get(LLVMTypes::Int32Type, width); // width
- Args[4] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 4); // stride
- Args[5] = llvm::ConstantInt::get(LLVMTypes::Int16Type, 0); // offsets
- Args[6] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 0); // parent width (ignored)
- Args[7] = Mask; // mask
+#endif
+ Args[1] = Val; // value to store
+ Args[2] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 0); // vstride
+ Args[3] = llvm::ConstantInt::get(LLVMTypes::Int32Type, width); // width
+ Args[4] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 4); // stride
+ Args[5] = llvm::ConstantInt::get(LLVMTypes::Int16Type, 0); // offsets
+ Args[6] = llvm::ConstantInt::get(LLVMTypes::Int32Type, 0); // parent width (ignored)
+ Args[7] = Mask; // mask
llvm::Type *Tys[4];
@@ -6708,7 +6774,12 @@ llvm::Instruction *FixAddressSpace::processGatherScatterPrivate(llvm::CallInst *
return NULL;
llvm::Value *address = calculateGatherScatterAddress(ptr, offsets, CI);
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
+ llvm::Type *i8VecType = llvm::FixedVectorType::get(LLVMTypes::Int8Type, width * 4);
+#else
llvm::Type *i8VecType = llvm::VectorType::get(LLVMTypes::Int8Type, width * 4);
+#endif
+
bool isInt8 = (value->getType()->getScalarType() == LLVMTypes::Int8Type);
Assert(address && "Bad gather/scatter address!");