From 8b4c392ef3de7140e1ac7089a52d8be15e162be6 Mon Sep 17 00:00:00 2001 From: Jakub Czarnecki Date: Tue, 10 Aug 2021 16:36:17 +0200 Subject: [PATCH 1/5] Fix for integer dot product translation --- lib/SPIRV/OCLToSPIRV.cpp | 99 ++++++++++++++++++- lib/SPIRV/OCLUtil.h | 7 ++ ...HR_integer_dot_product_OCLtoSPIRV_char4.ll | 83 ++++++++++++++++ ..._KHR_integer_dot_product_OCLtoSPIRV_int.ll | 82 +++++++++++++++ ...R_integer_dot_product_OCLtoSPIRV_short2.ll | 83 ++++++++++++++++ 5 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll create mode 100644 test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll create mode 100644 test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index e587fdb13c..6165347819 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -323,10 +323,22 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) { return; } if (DemangledName == kOCLBuiltinName::Dot && - !(CI.getOperand(0)->getType()->isVectorTy())) { + (CI.getOperand(0)->getType()->isFloatTy() || + CI.getOperand(1)->getType()->isDoubleTy())) { visitCallDot(&CI); return; } + if (DemangledName == kOCLBuiltinName::Dot || DemangledName == kOCLBuiltinName::Dot_Acc_Sat) { + if (CI.getOperand(0)->getType()->isVectorTy()) { + auto *VT = dyn_cast(CI.getOperand(0)->getType()); + if (!isa(VT->getElementType())) { + visitCallBuiltinSimple(&CI, MangledName, DemangledName); + return; + } + } + visitCallDot(&CI, MangledName, DemangledName); + return; + } if (DemangledName == kOCLBuiltinName::FMin || DemangledName == kOCLBuiltinName::FMax || DemangledName == kOCLBuiltinName::Min || @@ -1305,6 +1317,91 @@ void OCLToSPIRVBase::visitCallDot(CallInst *CI) { CI->eraseFromParent(); } +void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, + StringRef DemangledName) { + // translation for dot function calls, + // to differentiate between integer dot products + + SmallVector Args; + Args.push_back(CI->getOperand(0)); + Args.push_back(CI->getOperand(1)); + bool IsFirstSigned, IsSecondSigned; + bool IsDot = DemangledName == kOCLBuiltinName::Dot; + std::string funName = (IsDot) ? "DotKHR" : "DotAccSatKHR"; + if (CI->getNumArgOperands() > 2) { + Args.push_back(CI->getOperand(2)); + } + if (CI->getNumArgOperands() > 3) { + Args.push_back(CI->getOperand(3)); + } + if (CI->getOperand(0)->getType()->isVectorTy()) { + if (IsDot) { + // dot(char4, char4) @_Z3dotDv4_cS_ + // dot(char4, uchar4) @_Z3dotDv4_cDv4_h + // dot(uchar4, char4) @_Z3dotDv4_hDv4_c + // dot(uchar4, uchar4) @_Z3dotDv4_hS_ + // or + // dot(short2, short2) @_Z3dotDv2_sS_ + // dot(short2, ushort2) @_Z3dotDv2_sDv2_t + // dot(ushort2, short2) @_Z3dotDv2_tDv2_s + // dot(ushort2, ushort2) @_Z3dotDv2_tS_ + if (MangledName[MangledName.size() - 1] == '_') { + IsFirstSigned = ((MangledName[MangledName.size() - 3] == 'c') || + (MangledName[MangledName.size() - 3] == 's')); + IsSecondSigned = IsFirstSigned; + } else { + IsFirstSigned = ((MangledName[MangledName.size() - 6] == 'c') || + (MangledName[MangledName.size() - 6] == 's')); + IsSecondSigned = ((MangledName[MangledName.size() - 1] == 'c') || + (MangledName[MangledName.size() - 1] == 's')); + } + } else { + // dot_acc_sat(char4, char4, int) @_Z11dot_acc_satDv4_cS_i + // dot_acc_sat(char4, uchar4, int) @_Z11dot_acc_satDv4_cDv4_hi + // dot_acc_sat(uchar4, char4, int) @_Z11dot_acc_satDv4_hDv4_ci + // dot_acc_sat(uchar4, uchar4, uint) @_Z11dot_acc_satDv4_hS_j + // or + // dot_acc_sat(short2, short2, int) @_Z11dot_acc_satDv4_sS_i + // dot_acc_sat(short2, ushort2, int) @_Z11dot_acc_satDv4_sDv4_ti + // dot_acc_sat(ushort2, short2, int) @_Z11dot_acc_satDv4_tDv4_si + // dot_acc_sat(ushort2, ushort2, uint) @_Z11dot_acc_satDv4_tS_j + IsFirstSigned = ((MangledName[19] == 'c') || (MangledName[19] == 's')); + IsSecondSigned = (MangledName[20] == 'S' + ? IsFirstSigned + : ((MangledName[MangledName.size() - 2] == 'c') || + (MangledName[MangledName.size() - 2] == 's'))); + } + } else { + // for packed format + // dot(int, int, int) @_Z3dotiii + // dot(int, uint, int) @_Z3dotiji + // dot(uint, int, int) @_Z3dotjii + // dot(uint, uint, int) @_Z3dotjji + // or + // dot_acc_sat(int, int, int, int) @_Z11dot_acc_satiii + // dot_acc_sat(int, uint, int, int) @_Z11dot_acc_satiji + // dot_acc_sat(uint, int, int, int) @_Z11dot_acc_satjii + // dot_acc_sat(uint, uint, int, int) @_Z11dot_acc_satjji + IsFirstSigned = (IsDot) ? (MangledName[MangledName.size() - 3] == 'i') + : (MangledName[MangledName.size() - 4] == 'i'); + IsSecondSigned = (IsDot) ? (MangledName[MangledName.size() - 2] == 'i') + : (MangledName[MangledName.size() - 3] == 'i'); + } + std::string NamePref = + (IsFirstSigned != IsSecondSigned ? "SU" : ((IsFirstSigned) ? "S" : "U")); + std::string finName = "_Z" + + std::to_string(NamePref.size() + funName.size() + + strlen(kSPIRVName::Prefix)) + + kSPIRVName::Prefix + NamePref + funName; + StringRef opName = finName; + FunctionType *FT = FunctionType::get(CI->getType(), getTypes(Args), false); + FunctionCallee NewF = + CI->getFunction()->getParent()->getOrInsertFunction(opName, FT); + CallInst *NewCall = CallInst::Create(NewF, Args, "", CI); + CI->replaceAllUsesWith(NewCall); + CI->eraseFromParent(); +} + void OCLToSPIRVBase::visitCallScalToVec(CallInst *CI, StringRef MangledName, StringRef DemangledName) { // Check if all arguments have the same type - it's simple case. diff --git a/lib/SPIRV/OCLUtil.h b/lib/SPIRV/OCLUtil.h index da27fae84c..608889ce2b 100644 --- a/lib/SPIRV/OCLUtil.h +++ b/lib/SPIRV/OCLUtil.h @@ -233,6 +233,13 @@ const static char Barrier[] = "barrier"; const static char Clamp[] = "clamp"; const static char ConvertPrefix[] = "convert_"; const static char Dot[] = "dot"; +const static char Dot_Acc_Sat[] = "dot_acc_sat"; +const static char SDotKHR[] = "dot"; +const static char UDotKHR[] = "dot"; +const static char SUDotKHR[] = "dot"; +const static char SDotAccSatKHR[] = "dot_acc_sat"; +const static char UDotAccSatKHR[] = "dot_acc_sat"; +const static char SUDotAccSatKHR[] = "dot_acc_sat"; const static char EnqueueKernel[] = "enqueue_kernel"; const static char FixedSqrtINTEL[] = "intel_arbitrary_fixed_sqrt"; const static char FixedRecipINTEL[] = "intel_arbitrary_fixed_recip"; diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll new file mode 100644 index 0000000000..ea6673c7d1 --- /dev/null +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll @@ -0,0 +1,83 @@ +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM + +;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR + +;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-LLVM: SDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: UDotKHR + +;CHECK-LLVM: SDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: UDotAccSatKHR + +target datalayout = "e-p:32:32-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 = "spir" + +; Function Attrs: convergent norecurse nounwind +define spir_kernel void @test1(<4 x i8> %ia, <4 x i8> %ua, <4 x i8> %ib, <4 x i8> %ub, <4 x i8> %ires, <4 x i8> %ures) local_unnamed_addr #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !5 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 { +entry: + %call = tail call spir_func i32 @_Z3dotDv4_cS_(<4 x i8> %ia, <4 x i8> %ib) #2 + %call1 = tail call spir_func i32 @_Z3dotDv4_cDv4_h(<4 x i8> %ia, <4 x i8> %ub) #2 + %call2 = tail call spir_func i32 @_Z3dotDv4_hDv4_c(<4 x i8> %ua, <4 x i8> %ib) #2 + %call3 = tail call spir_func i32 @_Z3dotDv4_hS_(<4 x i8> %ua, <4 x i8> %ub) #2 + %call4 = tail call spir_func i32 @_Z11dot_acc_satDv4_cS_i(<4 x i8> %ia, <4 x i8> %ib, i32 %call2) #2 + %call5 = tail call spir_func i32 @_Z11dot_acc_satDv4_cDv4_hi(<4 x i8> %ia, <4 x i8> %ub, i32 %call4) #2 + %call6 = tail call spir_func i32 @_Z11dot_acc_satDv4_hDv4_ci(<4 x i8> %ua, <4 x i8> %ib, i32 %call5) #2 + %call7 = tail call spir_func i32 @_Z11dot_acc_satDv4_hS_j(<4 x i8> %ua, <4 x i8> %ub, i32 %call3) #2 + ret void +} + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv4_cS_(<4 x i8>, <4 x i8>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv4_cDv4_h(<4 x i8>, <4 x i8>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv4_hDv4_c(<4 x i8>, <4 x i8>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv4_hS_(<4 x i8>, <4 x i8>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv4_cS_i(<4 x i8>, <4 x i8>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv4_cDv4_hi(<4 x i8>, <4 x i8>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv4_hDv4_ci(<4 x i8>, <4 x i8>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv4_hS_j(<4 x i8>, <4 x i8>, i32) local_unnamed_addr #1 + +attributes #0 = { convergent norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pocharer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="128" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { convergent "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pocharer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { convergent nounwind } + +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 2, i32 0} +!2 = !{!"clang version 11.0.0 (https://github.com/c199914007/llvm.git 8b94769313ca84cb9370b60ed008501ff692cb71)"} +!3 = !{i32 0, i32 0, i32 0, i32 0, i32 0, i32 0} +!4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} +!5 = !{!"char4", !"uchar4", !"char4", !"uchar4", !"char4", !"uchar4"} +!6 = !{!"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))", !"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))", !"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))"} +!7 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll new file mode 100644 index 0000000000..b0faee5cbd --- /dev/null +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll @@ -0,0 +1,82 @@ +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM + +;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR + +;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-LLVM: SDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: UDotKHR + +;CHECK-LLVM: SDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: UDotAccSatKHR + +target datalayout = "e-p:32:32-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 = "spir" + +; Function Attrs: convergent norecurse nounwind +define spir_kernel void @test1(i32 %ia, i32 %ua, i32 %ib, i32 %ub, i32 %ires, i32 %ures) local_unnamed_addr #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !5 !kernel_arg_base_type !5 !kernel_arg_type_qual !6 { +entry: + %call = tail call spir_func i32 @_Z3dotiii(i32 %ia, i32 %ib, i32 0) #2 + %call1 = tail call spir_func i32 @_Z3dotiji(i32 %ia, i32 %ub, i32 0) #2 + %call2 = tail call spir_func i32 @_Z3dotjii(i32 %ua, i32 %ib, i32 0) #2 + %call3 = tail call spir_func i32 @_Z3dotjji(i32 %ua, i32 %ub, i32 0) #2 + %call4 = tail call spir_func i32 @_Z11dot_acc_satiiii(i32 %ia, i32 %ib, i32 %ires, i32 0) #2 + %call5 = tail call spir_func i32 @_Z11dot_acc_satijii(i32 %ia, i32 %ub, i32 %ires, i32 0) #2 + %call6 = tail call spir_func i32 @_Z11dot_acc_satjiii(i32 %ua, i32 %ib, i32 %ires, i32 0) #2 + %call7 = tail call spir_func i32 @_Z11dot_acc_satjjji(i32 %ua, i32 %ub, i32 %ures, i32 0) #2 + ret void +} + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotiii(i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotiji(i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotjii(i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotjji(i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satiiii(i32, i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satijii(i32, i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satjiii(i32, i32, i32, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satjjji(i32, i32, i32, i32) local_unnamed_addr #1 + +attributes #0 = { convergent norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { convergent "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { convergent nounwind } + +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 2, i32 0} +!2 = !{!"clang version 11.0.0 (https://github.com/c199914007/llvm.git f2b7028a3598d4d88ddf1f76b50946da4e135845)"} +!3 = !{i32 0, i32 0, i32 0, i32 0, i32 0, i32 0} +!4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} +!5 = !{!"int", !"uint", !"int", !"uint", !"int", !"uint"} +!6 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll new file mode 100644 index 0000000000..91e33b178c --- /dev/null +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll @@ -0,0 +1,83 @@ +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM + +;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR +;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR + +;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-LLVM: SDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: SUDotKHR +;CHECK-LLVM: UDotKHR + +;CHECK-LLVM: SDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: SUDotAccSatKHR +;CHECK-LLVM: UDotAccSatKHR + +target datalayout = "e-p:32:32-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 = "spir" + +; Function Attrs: convergent norecurse nounwind +define spir_kernel void @test1(<2 x i16> %ia, <2 x i16> %ua, <2 x i16> %ib, <2 x i16> %ub, <2 x i16> %ires, <2 x i16> %ures) local_unnamed_addr #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !5 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 { +entry: + %call = tail call spir_func i32 @_Z3dotDv2_sS_(<2 x i16> %ia, <2 x i16> %ib) #2 + %call1 = tail call spir_func i32 @_Z3dotDv2_sDv2_t(<2 x i16> %ia, <2 x i16> %ub) #2 + %call2 = tail call spir_func i32 @_Z3dotDv2_tDv2_s(<2 x i16> %ua, <2 x i16> %ib) #2 + %call3 = tail call spir_func i32 @_Z3dotDv2_tS_(<2 x i16> %ua, <2 x i16> %ub) #2 + %call4 = tail call spir_func i32 @_Z11dot_acc_satDv2_sS_i(<2 x i16> %ia, <2 x i16> %ib, i32 %call2) #2 + %call5 = tail call spir_func i32 @_Z11dot_acc_satDv2_sDv2_ti(<2 x i16> %ia, <2 x i16> %ub, i32 %call4) #2 + %call6 = tail call spir_func i32 @_Z11dot_acc_satDv2_tDv2_si(<2 x i16> %ua, <2 x i16> %ib, i32 %call5) #2 + %call7 = tail call spir_func i32 @_Z11dot_acc_satDv2_tS_j(<2 x i16> %ua, <2 x i16> %ub, i32 %call3) #2 + ret void +} + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv2_sS_(<2 x i16>, <2 x i16>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv2_sDv2_t(<2 x i16>, <2 x i16>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv2_tDv2_s(<2 x i16>, <2 x i16>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z3dotDv2_tS_(<2 x i16>, <2 x i16>) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv2_sS_i(<2 x i16>, <2 x i16>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv2_sDv2_ti(<2 x i16>, <2 x i16>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv2_tDv2_si(<2 x i16>, <2 x i16>, i32) local_unnamed_addr #1 + +; Function Attrs: convergent +declare spir_func i32 @_Z11dot_acc_satDv2_tS_j(<2 x i16>, <2 x i16>, i32) local_unnamed_addr #1 + +attributes #0 = { convergent norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pocharer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="128" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { convergent "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pocharer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { convergent nounwind } + +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 2, i32 0} +!2 = !{!"clang version 11.0.0 (https://github.com/c199914007/llvm.git 8b94769313ca84cb9370b60ed008501ff692cb71)"} +!3 = !{i32 0, i32 0, i32 0, i32 0, i32 0, i32 0} +!4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} +!5 = !{!"short4", !"ushort4", !"short4", !"ushort4", !"short4", !"ushort4"} +!6 = !{!"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))", !"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))", !"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))"} +!7 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file From d741153548b7b2da63c4a7bf53124f24aa2129ce Mon Sep 17 00:00:00 2001 From: Jakub Czarnecki Date: Mon, 23 Aug 2021 16:02:54 +0200 Subject: [PATCH 2/5] Additional translation for integer dot product Added additional translation when dot function is called in OpenCL with integer arguments (packed int or vectors of 4 chars or 2 shorts) so that it's translated into proper OpCodes from SPV_KHR_integer_dot_product extension and not OpDot, which works on floats. --- lib/SPIRV/OCLToSPIRV.cpp | 10 ++--- lib/SPIRV/OCLUtil.h | 6 --- ...HR_integer_dot_product_OCLtoSPIRV_char4.ll | 44 +++++++++---------- ..._KHR_integer_dot_product_OCLtoSPIRV_int.ll | 44 +++++++++---------- ...R_integer_dot_product_OCLtoSPIRV_short2.ll | 44 +++++++++---------- 5 files changed, 71 insertions(+), 77 deletions(-) diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index 6165347819..fd6647fd8d 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -330,7 +330,7 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) { } if (DemangledName == kOCLBuiltinName::Dot || DemangledName == kOCLBuiltinName::Dot_Acc_Sat) { if (CI.getOperand(0)->getType()->isVectorTy()) { - auto *VT = dyn_cast(CI.getOperand(0)->getType()); + auto *VT = (VectorType *)(CI.getOperand(0)->getType()); if (!isa(VT->getElementType())) { visitCallBuiltinSimple(&CI, MangledName, DemangledName); return; @@ -1378,10 +1378,10 @@ void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, // dot(uint, int, int) @_Z3dotjii // dot(uint, uint, int) @_Z3dotjji // or - // dot_acc_sat(int, int, int, int) @_Z11dot_acc_satiii - // dot_acc_sat(int, uint, int, int) @_Z11dot_acc_satiji - // dot_acc_sat(uint, int, int, int) @_Z11dot_acc_satjii - // dot_acc_sat(uint, uint, int, int) @_Z11dot_acc_satjji + // dot_acc_sat(int, int, int, int) @_Z11dot_acc_satiiii + // dot_acc_sat(int, uint, int, int) @_Z11dot_acc_satijii + // dot_acc_sat(uint, int, int, int) @_Z11dot_acc_satjiii + // dot_acc_sat(uint, uint, int, int) @_Z11dot_acc_satjjii IsFirstSigned = (IsDot) ? (MangledName[MangledName.size() - 3] == 'i') : (MangledName[MangledName.size() - 4] == 'i'); IsSecondSigned = (IsDot) ? (MangledName[MangledName.size() - 2] == 'i') diff --git a/lib/SPIRV/OCLUtil.h b/lib/SPIRV/OCLUtil.h index 608889ce2b..40353ee754 100644 --- a/lib/SPIRV/OCLUtil.h +++ b/lib/SPIRV/OCLUtil.h @@ -234,12 +234,6 @@ const static char Clamp[] = "clamp"; const static char ConvertPrefix[] = "convert_"; const static char Dot[] = "dot"; const static char Dot_Acc_Sat[] = "dot_acc_sat"; -const static char SDotKHR[] = "dot"; -const static char UDotKHR[] = "dot"; -const static char SUDotKHR[] = "dot"; -const static char SDotAccSatKHR[] = "dot_acc_sat"; -const static char UDotAccSatKHR[] = "dot_acc_sat"; -const static char SUDotAccSatKHR[] = "dot_acc_sat"; const static char EnqueueKernel[] = "enqueue_kernel"; const static char FixedSqrtINTEL[] = "intel_arbitrary_fixed_sqrt"; const static char FixedRecipINTEL[] = "intel_arbitrary_fixed_recip"; diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll index ea6673c7d1..02ec2e4cd7 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll @@ -1,27 +1,27 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV -; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM - -;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR - -;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR - -;CHECK-LLVM: SDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: UDotKHR - -;CHECK-LLVM: SDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: UDotAccSatKHR +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV + +;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR + +;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-SPIRV: SDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: UDotKHR + +;CHECK-SPIRV: SDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: UDotAccSatKHR target datalayout = "e-p:32:32-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 = "spir" diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll index b0faee5cbd..96aa3e6bf2 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll @@ -1,27 +1,27 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV -; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM - -;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR - -;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR - -;CHECK-LLVM: SDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: UDotKHR - -;CHECK-LLVM: SDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: UDotAccSatKHR +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV + +;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR + +;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-SPIRV: SDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: UDotKHR + +;CHECK-SPIRV: SDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: UDotAccSatKHR target datalayout = "e-p:32:32-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 = "spir" diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll index 91e33b178c..fc8ce16f51 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll @@ -1,27 +1,27 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV -; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-LLVM - -;CHECK-SPIRV: call i32 @_Z15__spirv_SDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z16__spirv_SUDotKHR -;CHECK-SPIRV: call i32 @_Z15__spirv_UDotKHR - -;CHECK-SPIRV: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-SPIRV: call i32 @_Z21__spirv_UDotAccSatKHR - -;CHECK-LLVM: SDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: SUDotKHR -;CHECK-LLVM: UDotKHR - -;CHECK-LLVM: SDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: SUDotAccSatKHR -;CHECK-LLVM: UDotAccSatKHR +; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM +; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV + +;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR + +;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR + +;CHECK-SPIRV: SDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: SUDotKHR +;CHECK-SPIRV: UDotKHR + +;CHECK-SPIRV: SDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: SUDotAccSatKHR +;CHECK-SPIRV: UDotAccSatKHR target datalayout = "e-p:32:32-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 = "spir" From 8bcc2b970e68406e3f527d00c4c0ef845f138a44 Mon Sep 17 00:00:00 2001 From: Jakub Czarnecki Date: Mon, 23 Aug 2021 16:02:54 +0200 Subject: [PATCH 3/5] Additional translation for integer dot product Added additional translation when dot function is called in OpenCL with integer arguments (packed int or vectors of 4 chars or 2 shorts) so that it's translated into proper OpCodes from SPV_KHR_integer_dot_product extension and not OpDot, which works on floats. --- lib/SPIRV/OCLToSPIRV.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index fd6647fd8d..8ce1a40417 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -1327,7 +1327,7 @@ void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, Args.push_back(CI->getOperand(1)); bool IsFirstSigned, IsSecondSigned; bool IsDot = DemangledName == kOCLBuiltinName::Dot; - std::string funName = (IsDot) ? "DotKHR" : "DotAccSatKHR"; + std::string FunName = (IsDot) ? "DotKHR" : "DotAccSatKHR"; if (CI->getNumArgOperands() > 2) { Args.push_back(CI->getOperand(2)); } @@ -1389,14 +1389,28 @@ void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, } std::string NamePref = (IsFirstSigned != IsSecondSigned ? "SU" : ((IsFirstSigned) ? "S" : "U")); - std::string finName = "_Z" + - std::to_string(NamePref.size() + funName.size() + + std::string FinName = "_Z" + + std::to_string(NamePref.size() + FunName.size() + strlen(kSPIRVName::Prefix)) + - kSPIRVName::Prefix + NamePref + funName; - StringRef opName = finName; + kSPIRVName::Prefix + NamePref + FunName; + StringRef OpName = FinName; + // If arguments are in order unsigned -> signed, then the translator should + // swap them, so that the OpSUDotKHR can be used properly + if (IsFirstSigned == false && IsSecondSigned == true) + { + Args.clear(); + Args.push_back(CI->getOperand(1)); + Args.push_back(CI->getOperand(0)); + if (CI->getNumArgOperands() > 2) { + Args.push_back(CI->getOperand(2)); + } + if (CI->getNumArgOperands() > 3) { + Args.push_back(CI->getOperand(3)); + } + } FunctionType *FT = FunctionType::get(CI->getType(), getTypes(Args), false); FunctionCallee NewF = - CI->getFunction()->getParent()->getOrInsertFunction(opName, FT); + CI->getFunction()->getParent()->getOrInsertFunction(OpName, FT); CallInst *NewCall = CallInst::Create(NewF, Args, "", CI); CI->replaceAllUsesWith(NewCall); CI->eraseFromParent(); From e2c96a458b64eece972318e35a4c3b9bfe5f6cf2 Mon Sep 17 00:00:00 2001 From: Jakub Czarnecki Date: Thu, 14 Jul 2022 16:50:53 +0200 Subject: [PATCH 4/5] Integer dot product translation fix - update Fixed translation of IR from source when dot function is called with integer arguments (ints, vectors of chars or shorts) to properly support cl_khr_integer_dot_product extension. Previously dot would always be translated to its version with floating point arguments. Additionally updated with suggested changes. --- lib/SPIRV/OCLToSPIRV.cpp | 138 +++++++++--------- lib/SPIRV/OCLToSPIRV.h | 5 + ...HR_integer_dot_product_OCLtoSPIRV_char4.ll | 4 +- ..._KHR_integer_dot_product_OCLtoSPIRV_int.ll | 4 +- ...R_integer_dot_product_OCLtoSPIRV_short2.ll | 4 +- 5 files changed, 87 insertions(+), 68 deletions(-) diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index 8ce1a40417..f0caaf8200 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -1317,8 +1317,8 @@ void OCLToSPIRVBase::visitCallDot(CallInst *CI) { CI->eraseFromParent(); } -void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, - StringRef DemangledName) { +void OCLToSPIRVBase::visitCallDot(CallInst *CI, StringRef MangledName, + StringRef DemangledName) { // translation for dot function calls, // to differentiate between integer dot products @@ -1328,43 +1328,45 @@ void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, bool IsFirstSigned, IsSecondSigned; bool IsDot = DemangledName == kOCLBuiltinName::Dot; std::string FunName = (IsDot) ? "DotKHR" : "DotAccSatKHR"; - if (CI->getNumArgOperands() > 2) { + if (CI->arg_size() > 2) { Args.push_back(CI->getOperand(2)); } - if (CI->getNumArgOperands() > 3) { + if (CI->arg_size() > 3) { Args.push_back(CI->getOperand(3)); } if (CI->getOperand(0)->getType()->isVectorTy()) { if (IsDot) { - // dot(char4, char4) @_Z3dotDv4_cS_ - // dot(char4, uchar4) @_Z3dotDv4_cDv4_h - // dot(uchar4, char4) @_Z3dotDv4_hDv4_c - // dot(uchar4, uchar4) @_Z3dotDv4_hS_ + // dot(char4, char4) _Z3dotDv4_cS_ + // dot(char4, uchar4) _Z3dotDv4_cDv4_h + // dot(uchar4, char4) _Z3dotDv4_hDv4_c + // dot(uchar4, uchar4) _Z3dotDv4_hS_ // or - // dot(short2, short2) @_Z3dotDv2_sS_ - // dot(short2, ushort2) @_Z3dotDv2_sDv2_t - // dot(ushort2, short2) @_Z3dotDv2_tDv2_s - // dot(ushort2, ushort2) @_Z3dotDv2_tS_ + // dot(short2, short2) _Z3dotDv2_sS_ + // dot(short2, ushort2) _Z3dotDv2_sDv2_t + // dot(ushort2, short2) _Z3dotDv2_tDv2_s + // dot(ushort2, ushort2) _Z3dotDv2_tS_ + assert(MangledName.startswith("_Z3dotDv")); if (MangledName[MangledName.size() - 1] == '_') { - IsFirstSigned = ((MangledName[MangledName.size() - 3] == 'c') || - (MangledName[MangledName.size() - 3] == 's')); + IsFirstSigned = ((MangledName[MangledName.size() - 3] == 'c') || + (MangledName[MangledName.size() - 3] == 's')); IsSecondSigned = IsFirstSigned; } else { IsFirstSigned = ((MangledName[MangledName.size() - 6] == 'c') || - (MangledName[MangledName.size() - 6] == 's')); + (MangledName[MangledName.size() - 6] == 's')); IsSecondSigned = ((MangledName[MangledName.size() - 1] == 'c') || - (MangledName[MangledName.size() - 1] == 's')); + (MangledName[MangledName.size() - 1] == 's')); } } else { - // dot_acc_sat(char4, char4, int) @_Z11dot_acc_satDv4_cS_i - // dot_acc_sat(char4, uchar4, int) @_Z11dot_acc_satDv4_cDv4_hi - // dot_acc_sat(uchar4, char4, int) @_Z11dot_acc_satDv4_hDv4_ci - // dot_acc_sat(uchar4, uchar4, uint) @_Z11dot_acc_satDv4_hS_j + // dot_acc_sat(char4, char4, int) _Z11dot_acc_satDv4_cS_i + // dot_acc_sat(char4, uchar4, int) _Z11dot_acc_satDv4_cDv4_hi + // dot_acc_sat(uchar4, char4, int) _Z11dot_acc_satDv4_hDv4_ci + // dot_acc_sat(uchar4, uchar4, uint) _Z11dot_acc_satDv4_hS_j // or - // dot_acc_sat(short2, short2, int) @_Z11dot_acc_satDv4_sS_i - // dot_acc_sat(short2, ushort2, int) @_Z11dot_acc_satDv4_sDv4_ti - // dot_acc_sat(ushort2, short2, int) @_Z11dot_acc_satDv4_tDv4_si - // dot_acc_sat(ushort2, ushort2, uint) @_Z11dot_acc_satDv4_tS_j + // dot_acc_sat(short2, short2, int) _Z11dot_acc_satDv4_sS_i + // dot_acc_sat(short2, ushort2, int) _Z11dot_acc_satDv4_sDv4_ti + // dot_acc_sat(ushort2, short2, int) _Z11dot_acc_satDv4_tDv4_si + // dot_acc_sat(ushort2, ushort2, uint) _Z11dot_acc_satDv4_tS_j + assert(MangledName.startswith("_Z11dot_acc_satDv")); IsFirstSigned = ((MangledName[19] == 'c') || (MangledName[19] == 's')); IsSecondSigned = (MangledName[20] == 'S' ? IsFirstSigned @@ -1372,48 +1374,54 @@ void OCLToSPIRVBase::visitCallDot(CallInst* CI, StringRef MangledName, (MangledName[MangledName.size() - 2] == 's'))); } } else { - // for packed format - // dot(int, int, int) @_Z3dotiii - // dot(int, uint, int) @_Z3dotiji - // dot(uint, int, int) @_Z3dotjii - // dot(uint, uint, int) @_Z3dotjji - // or - // dot_acc_sat(int, int, int, int) @_Z11dot_acc_satiiii - // dot_acc_sat(int, uint, int, int) @_Z11dot_acc_satijii - // dot_acc_sat(uint, int, int, int) @_Z11dot_acc_satjiii - // dot_acc_sat(uint, uint, int, int) @_Z11dot_acc_satjjii - IsFirstSigned = (IsDot) ? (MangledName[MangledName.size() - 3] == 'i') - : (MangledName[MangledName.size() - 4] == 'i'); - IsSecondSigned = (IsDot) ? (MangledName[MangledName.size() - 2] == 'i') - : (MangledName[MangledName.size() - 3] == 'i'); - } - std::string NamePref = - (IsFirstSigned != IsSecondSigned ? "SU" : ((IsFirstSigned) ? "S" : "U")); - std::string FinName = "_Z" + - std::to_string(NamePref.size() + FunName.size() + - strlen(kSPIRVName::Prefix)) + - kSPIRVName::Prefix + NamePref + FunName; - StringRef OpName = FinName; - // If arguments are in order unsigned -> signed, then the translator should - // swap them, so that the OpSUDotKHR can be used properly - if (IsFirstSigned == false && IsSecondSigned == true) - { - Args.clear(); - Args.push_back(CI->getOperand(1)); - Args.push_back(CI->getOperand(0)); - if (CI->getNumArgOperands() > 2) { - Args.push_back(CI->getOperand(2)); - } - if (CI->getNumArgOperands() > 3) { - Args.push_back(CI->getOperand(3)); - } + // for packed format + // dot(int, int, int) _Z3dotiii + // dot(int, uint, int) _Z3dotiji + // dot(uint, int, int) _Z3dotjii + // dot(uint, uint, int) _Z3dotjji + // or + // dot_acc_sat(int, int, int, int) _Z11dot_acc_satiiii + // dot_acc_sat(int, uint, int, int) _Z11dot_acc_satijii + // dot_acc_sat(uint, int, int, int) _Z11dot_acc_satjiii + // dot_acc_sat(uint, uint, int, int) _Z11dot_acc_satjjii + assert(MangledName.startswith("_Z3dot") || + MangledName.startswith("_Z11dot_acc_sat")); + IsFirstSigned = (IsDot) ? (MangledName[MangledName.size() - 3] == 'i') + : (MangledName[MangledName.size() - 4] == 'i'); + IsSecondSigned = (IsDot) ? (MangledName[MangledName.size() - 2] == 'i') + : (MangledName[MangledName.size() - 3] == 'i'); } - FunctionType *FT = FunctionType::get(CI->getType(), getTypes(Args), false); - FunctionCallee NewF = - CI->getFunction()->getParent()->getOrInsertFunction(OpName, FT); - CallInst *NewCall = CallInst::Create(NewF, Args, "", CI); - CI->replaceAllUsesWith(NewCall); - CI->eraseFromParent(); + AttributeList Attrs = CI->getCalledFunction()->getAttributes(); + mutateCallInstSPIRV( + M, CI, + [=](CallInst *, std::vector &Args /*, Type *&Ret*/) { + // If arguments are in order unsigned -> signed + // then the translator shouldswap them, + // so that the OpSUDotKHR can be used properly + if (IsFirstSigned == false && IsSecondSigned == true) { + Args.clear(); + Args.push_back(CI->getOperand(1)); + Args.push_back(CI->getOperand(0)); + if (CI->arg_size() > 2) { + Args.push_back(CI->getOperand(2)); + } + if (CI->arg_size() > 3) { + Args.push_back(CI->getOperand(3)); + } + } + Op OC; + if (IsDot) { + OC = (IsFirstSigned != IsSecondSigned + ? OpSUDot + : ((IsFirstSigned) ? OpSDot : OpUDot)); + } else { + OC = (IsFirstSigned != IsSecondSigned + ? OpSUDotAccSat + : ((IsFirstSigned) ? OpSDotAccSat : OpUDotAccSat)); + } + return getSPIRVFuncName(OC); + }, + &Attrs); } void OCLToSPIRVBase::visitCallScalToVec(CallInst *CI, StringRef MangledName, diff --git a/lib/SPIRV/OCLToSPIRV.h b/lib/SPIRV/OCLToSPIRV.h index c99f33496e..7b1c3086e2 100644 --- a/lib/SPIRV/OCLToSPIRV.h +++ b/lib/SPIRV/OCLToSPIRV.h @@ -210,6 +210,11 @@ class OCLToSPIRVBase : public InstVisitor { /// Transforms OpDot instructions with a scalar type to a fmul instruction void visitCallDot(CallInst *CI); + /// Transforms OpDot instructions with a vector or scalar (packed vector) type + /// to dot or dot_acc_sat instructions + void visitCallDot(CallInst *CI, StringRef MangledName, + StringRef DemangledName); + /// Fixes for built-in functions with vector+scalar arguments that are /// translated to the SPIR-V instructions where all arguments must have the /// same type. diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll index 02ec2e4cd7..342a91dbca 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV @@ -80,4 +82,4 @@ attributes #2 = { convergent nounwind } !4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} !5 = !{!"char4", !"uchar4", !"char4", !"uchar4", !"char4", !"uchar4"} !6 = !{!"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))", !"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))", !"char __attribute__((ext_vector_type(4)))", !"uchar __attribute__((ext_vector_type(4)))"} -!7 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file +!7 = !{!"", !"", !"", !"", !"", !""} diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll index 96aa3e6bf2..508b53a95c 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV @@ -79,4 +81,4 @@ attributes #2 = { convergent nounwind } !3 = !{i32 0, i32 0, i32 0, i32 0, i32 0, i32 0} !4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} !5 = !{!"int", !"uint", !"int", !"uint", !"int", !"uint"} -!6 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file +!6 = !{!"", !"", !"", !"", !"", !""} diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll index fc8ce16f51..048cf355d7 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV @@ -80,4 +82,4 @@ attributes #2 = { convergent nounwind } !4 = !{!"none", !"none", !"none", !"none", !"none", !"none"} !5 = !{!"short4", !"ushort4", !"short4", !"ushort4", !"short4", !"ushort4"} !6 = !{!"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))", !"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))", !"short __attribute__((ext_vector_type(4)))", !"ushort __attribute__((ext_vector_type(4)))"} -!7 = !{!"", !"", !"", !"", !"", !""} \ No newline at end of file +!7 = !{!"", !"", !"", !"", !"", !""} From 08ac08673bbb1e4810e73ea330c4e9b4a339be7a Mon Sep 17 00:00:00 2001 From: Jakub Czarnecki Date: Wed, 20 Jul 2022 15:12:13 +0200 Subject: [PATCH 5/5] Integer dot product translation quickfix Fixed some small mistakes in comments; added extension in tests and changed one variable name to resolve CI issues. Additionally refactored argument swapping as per suggestion. --- lib/SPIRV/OCLToSPIRV.cpp | 49 ++++++++----------- lib/SPIRV/OCLUtil.h | 2 +- ...HR_integer_dot_product_OCLtoSPIRV_char4.ll | 18 +++---- ..._KHR_integer_dot_product_OCLtoSPIRV_int.ll | 18 +++---- ...R_integer_dot_product_OCLtoSPIRV_short2.ll | 18 +++---- 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index f0caaf8200..49d2857ed0 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -328,7 +328,8 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) { visitCallDot(&CI); return; } - if (DemangledName == kOCLBuiltinName::Dot || DemangledName == kOCLBuiltinName::Dot_Acc_Sat) { + if (DemangledName == kOCLBuiltinName::Dot || + DemangledName == kOCLBuiltinName::DotAccSat) { if (CI.getOperand(0)->getType()->isVectorTy()) { auto *VT = (VectorType *)(CI.getOperand(0)->getType()); if (!isa(VT->getElementType())) { @@ -1393,35 +1394,27 @@ void OCLToSPIRVBase::visitCallDot(CallInst *CI, StringRef MangledName, } AttributeList Attrs = CI->getCalledFunction()->getAttributes(); mutateCallInstSPIRV( - M, CI, - [=](CallInst *, std::vector &Args /*, Type *&Ret*/) { - // If arguments are in order unsigned -> signed - // then the translator shouldswap them, - // so that the OpSUDotKHR can be used properly - if (IsFirstSigned == false && IsSecondSigned == true) { - Args.clear(); - Args.push_back(CI->getOperand(1)); - Args.push_back(CI->getOperand(0)); - if (CI->arg_size() > 2) { - Args.push_back(CI->getOperand(2)); + M, CI, + [=](CallInst *, std::vector &Args) { + // If arguments are in order unsigned -> signed + // then the translator should swap them, + // so that the OpSUDotKHR can be used properly + if (IsFirstSigned == false && IsSecondSigned == true) { + std::swap(Args[0], Args[1]); } - if (CI->arg_size() > 3) { - Args.push_back(CI->getOperand(3)); + Op OC; + if (IsDot) { + OC = (IsFirstSigned != IsSecondSigned + ? OpSUDot + : ((IsFirstSigned) ? OpSDot : OpUDot)); + } else { + OC = (IsFirstSigned != IsSecondSigned + ? OpSUDotAccSat + : ((IsFirstSigned) ? OpSDotAccSat : OpUDotAccSat)); } - } - Op OC; - if (IsDot) { - OC = (IsFirstSigned != IsSecondSigned - ? OpSUDot - : ((IsFirstSigned) ? OpSDot : OpUDot)); - } else { - OC = (IsFirstSigned != IsSecondSigned - ? OpSUDotAccSat - : ((IsFirstSigned) ? OpSDotAccSat : OpUDotAccSat)); - } - return getSPIRVFuncName(OC); - }, - &Attrs); + return getSPIRVFuncName(OC); + }, + &Attrs); } void OCLToSPIRVBase::visitCallScalToVec(CallInst *CI, StringRef MangledName, diff --git a/lib/SPIRV/OCLUtil.h b/lib/SPIRV/OCLUtil.h index 40353ee754..6497ecb6ed 100644 --- a/lib/SPIRV/OCLUtil.h +++ b/lib/SPIRV/OCLUtil.h @@ -233,7 +233,7 @@ const static char Barrier[] = "barrier"; const static char Clamp[] = "clamp"; const static char ConvertPrefix[] = "convert_"; const static char Dot[] = "dot"; -const static char Dot_Acc_Sat[] = "dot_acc_sat"; +const static char DotAccSat[] = "dot_acc_sat"; const static char EnqueueKernel[] = "enqueue_kernel"; const static char FixedSqrtINTEL[] = "intel_arbitrary_fixed_sqrt"; const static char FixedRecipINTEL[] = "intel_arbitrary_fixed_recip"; diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll index 342a91dbca..3a0f3a873a 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_char4.ll @@ -1,19 +1,19 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_integer_dot_product -o %t-spirv.spv ; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV -;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_UDotKHR -;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_UDotAccSatKHR ;CHECK-SPIRV: SDotKHR ;CHECK-SPIRV: SUDotKHR diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll index 508b53a95c..7a7b5cab2d 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_int.ll @@ -1,19 +1,19 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_integer_dot_product -o %t-spirv.spv ; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV -;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_UDotKHR -;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_UDotAccSatKHR ;CHECK-SPIRV: SDotKHR ;CHECK-SPIRV: SUDotKHR diff --git a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll index 048cf355d7..54c5ab9c17 100644 --- a/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll +++ b/test/transcoding/SPV_KHR_integer_dot_product_OCLtoSPIRV_short2.ll @@ -1,19 +1,19 @@ ; RUN: llvm-as < %s -o %t.bc ; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc -; RUN: llvm-spirv %t.bc -o %t-spirv.spv +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_integer_dot_product -o %t-spirv.spv ; RUN: spirv-val %t-spirv.spv ; RUN: llvm-dis %t.regularized.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; RUN: llvm-spirv %t.bc -spirv-text --spirv-ext=+SPV_KHR_integer_dot_product -o - | FileCheck %s --check-prefix=CHECK-SPIRV -;CHECK-LLVM: call i32 @_Z15__spirv_SDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z16__spirv_SUDotKHR -;CHECK-LLVM: call i32 @_Z15__spirv_UDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_SDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z16__spirv_SUDotKHR +;CHECK-LLVM: call spir_func i32 @_Z15__spirv_UDotKHR -;CHECK-LLVM: call i32 @_Z21__spirv_SDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z22__spirv_SUDotAccSatKHR -;CHECK-LLVM: call i32 @_Z21__spirv_UDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_SDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z22__spirv_SUDotAccSatKHR +;CHECK-LLVM: call spir_func i32 @_Z21__spirv_UDotAccSatKHR ;CHECK-SPIRV: SDotKHR ;CHECK-SPIRV: SUDotKHR