std::vector<uint32_t> &MemoryAccess,
SPIRVWord MemAccessMask) {
if (!BM->isAllowedToUseExtension(
- ExtensionID::SPV_INTEL_memory_access_aliasing))
+ ExtensionID::SPV_INTEL_memory_access_aliasing))
return;
auto *MemAliasList = addMemAliasingINTELInstructions(BM, AliasingListMD);
if (!MemAliasList)
void LLVMToSPIRVBase::transMemAliasingINTELDecorations(Instruction *Inst,
SPIRVValue *BV) {
if (!BM->isAllowedToUseExtension(
- ExtensionID::SPV_INTEL_memory_access_aliasing))
+ ExtensionID::SPV_INTEL_memory_access_aliasing))
return;
- if (MDNode *AliasingListMD =
- Inst->getMetadata(LLVMContext::MD_alias_scope)) {
- auto *MemAliasList =
- addMemAliasingINTELInstructions(BM, AliasingListMD);
+ if (MDNode *AliasingListMD = Inst->getMetadata(LLVMContext::MD_alias_scope)) {
+ auto *MemAliasList = addMemAliasingINTELInstructions(BM, AliasingListMD);
if (!MemAliasList)
return;
BV->addDecorate(new SPIRVDecorateId(DecorationAliasScopeINTEL, BV,
MemAliasList->getId()));
}
if (MDNode *AliasingListMD = Inst->getMetadata(LLVMContext::MD_noalias)) {
- auto *MemAliasList =
- addMemAliasingINTELInstructions(BM, AliasingListMD);
+ auto *MemAliasList = addMemAliasingINTELInstructions(BM, AliasingListMD);
if (!MemAliasList)
return;
BV->addDecorate(
}
}
+static SPIRVWord getNativeBuiltinIdForIntrinsic(Intrinsic::ID IID) {
+ switch (IID) {
+ case Intrinsic::cos:
+ return OpenCLLIB::Native_cos;
+ case Intrinsic::exp:
+ return OpenCLLIB::Native_exp;
+ case Intrinsic::exp2:
+ return OpenCLLIB::Native_exp2;
+ case Intrinsic::log:
+ return OpenCLLIB::Native_log;
+ case Intrinsic::log10:
+ return OpenCLLIB::Native_log10;
+ case Intrinsic::log2:
+ return OpenCLLIB::Native_log2;
+ case Intrinsic::sin:
+ return OpenCLLIB::Native_sin;
+ case Intrinsic::sqrt:
+ return OpenCLLIB::Native_sqrt;
+ default:
+ return getBuiltinIdForIntrinsic(IID);
+ }
+}
+
+static bool allowsApproxFunction(IntrinsicInst *II) {
+ auto *Ty = II->getType();
+ // OpenCL native_* built-ins only support single precision data type
+ return II->hasApproxFunc() &&
+ (Ty->isFloatTy() ||
+ (Ty->isVectorTy() &&
+ cast<VectorType>(Ty)->getElementType()->isFloatTy()));
+}
+
SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
SPIRVBasicBlock *BB) {
auto GetMemoryAccess = [](MemIntrinsic *MI) -> std::vector<SPIRVWord> {
// LLVM intrinsics with known translation to SPIR-V are handled here. They
// also must be registered at isKnownIntrinsic function in order to make
// -spirv-allow-unknown-intrinsics work correctly.
- switch (II->getIntrinsicID()) {
+ auto IID = II->getIntrinsicID();
+ switch (IID) {
case Intrinsic::assume: {
// llvm.assume translation is currently supported only within
// SPV_KHR_expect_assume extension, ignore it otherwise, since it's
case Intrinsic::trunc: {
if (!checkTypeForSPIRVExtendedInstLowering(II, BM))
break;
- SPIRVWord ExtOp = getBuiltinIdForIntrinsic(II->getIntrinsicID());
+ const SPIRVWord ExtOp = allowsApproxFunction(II)
+ ? getNativeBuiltinIdForIntrinsic(IID)
+ : getBuiltinIdForIntrinsic(IID);
SPIRVType *STy = transType(II->getType());
std::vector<SPIRVValue *> Ops(1, transValue(II->getArgOperand(0), BB));
return BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops,
case Intrinsic::minnum: {
if (!checkTypeForSPIRVExtendedInstLowering(II, BM))
break;
- SPIRVWord ExtOp = getBuiltinIdForIntrinsic(II->getIntrinsicID());
+ const SPIRVWord ExtOp = allowsApproxFunction(II)
+ ? getNativeBuiltinIdForIntrinsic(IID)
+ : getBuiltinIdForIntrinsic(IID);
SPIRVType *STy = transType(II->getType());
std::vector<SPIRVValue *> Ops{transValue(II->getArgOperand(0), BB),
transValue(II->getArgOperand(1), BB)};
SPIRVValue *FirstArgVal = transValue(II->getArgOperand(0), BB);
SPIRVValue *SecondArgVal = transValue(II->getArgOperand(1), BB);
- Op OC = (II->getIntrinsicID() == Intrinsic::smin)
- ? OpSLessThan
- : ((II->getIntrinsicID() == Intrinsic::smax)
- ? OpSGreaterThan
- : ((II->getIntrinsicID() == Intrinsic::umin)
- ? OpULessThan
- : OpUGreaterThan));
+ const Op OC =
+ (IID == Intrinsic::smin)
+ ? OpSLessThan
+ : ((IID == Intrinsic::smax)
+ ? OpSGreaterThan
+ : ((IID == Intrinsic::umin) ? OpULessThan : OpUGreaterThan));
if (auto *VecTy = dyn_cast<VectorType>(II->getArgOperand(0)->getType()))
BoolTy = VectorType::get(BoolTy, VecTy->getElementCount());
SPIRVValue *Cmp =
}
case Intrinsic::ctlz:
case Intrinsic::cttz: {
- SPIRVWord ExtOp = II->getIntrinsicID() == Intrinsic::ctlz ? OpenCLLIB::Clz
- : OpenCLLIB::Ctz;
+ const SPIRVWord ExtOp =
+ IID == Intrinsic::ctlz ? OpenCLLIB::Clz : OpenCLLIB::Ctz;
SPIRVType *Ty = transType(II->getType());
std::vector<SPIRVValue *> Ops(1, transValue(II->getArgOperand(0), BB));
return BM->addExtInst(Ty, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops,
else
// Other LLVM intrinsics shouldn't get to SPIRV, because they
// can't be represented in SPIRV or aren't implemented yet.
- BM->SPIRVCK(
- false, InvalidFunctionCall, II->getCalledOperand()->getName().str());
+ BM->SPIRVCK(false, InvalidFunctionCall,
+ II->getCalledOperand()->getName().str());
}
return nullptr;
}
--- /dev/null
+; RUN: llvm-as %s -o %t.bc
+; RUN: not llvm-spirv -s %t.bc
+; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_vector_compute %t.bc
+; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s
+
+; CHECK: ExtInstImport [[ExtInstSetId:[0-9]+]] "OpenCL.std"
+; CHECK: TypeFloat [[Float:[0-9]+]] 32
+; CHECK: TypeVector [[Float5:[0-9]+]] [[Float]] 5
+
+; ModuleID = 'lower-non-standard-vec-with-ext'
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
+target triple = "spir64-unknown-unknown"
+
+@Id = external dso_local local_unnamed_addr addrspace(1) constant <3 x i64>, align 32
+
+declare <5 x float> @llvm.sqrt.f32(<5 x float> %x)
+
+; Function Attrs: convergent norecurse
+define dso_local spir_func <5 x float> @test_sqrt(<5 x float> %src) local_unnamed_addr #0 !sycl_explicit_simd !4 !intel_reqd_sub_group_size !6 {
+entry:
+ %res = call <5 x float> @llvm.sqrt.f32(<5 x float> %src)
+; CHECK: ExtInst [[Float5]] {{[0-9]+}} [[ExtInstSetId]] sqrt
+ ret <5 x float> %res
+}
+
+attributes #0 = { convergent norecurse "frame-pointer"="all" "min-legal-vector-width"="256" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="lower-external-funcs-with-z.cpp" }
+
+!llvm.module.flags = !{!0, !1}
+!opencl.spir.version = !{!2}
+!spirv.Source = !{!3}
+!opencl.used.extensions = !{!4}
+!opencl.used.optional.core.features = !{!4}
+!opencl.compiler.options = !{!4}
+!llvm.ident = !{!5}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{i32 1, i32 2}
+!3 = !{i32 0, i32 100000}
+!4 = !{}
+!5 = !{!"Compiler"}
+!6 = !{i32 1}