Skip to content

Commit 21edac2

Browse files
authored
[SPIRV] Add Target Builtins using Distance ext as an example (#121598)
- Update pr labeler so new SPIRV files get properly labeled. - Add distance target builtin to BuiltinsSPIRV.td. - Update TargetBuiltins.h to account for spirv builtins. - Update clang basic CMakeLists.txt to build spirv builtin tablegen. - Hook up sema for SPIRV in Sema.h|cpp, SemaSPIRV.h|cpp, and SemaChecking.cpp. - Hookup sprv target builtins to SPIR.h|SPIR.cpp target. - Update GBuiltin.cpp to emit spirv intrinsics when we get the expected spirv target builtin. Consensus was reach in this RFC to add both target builtins and pattern matching: https://discourse.llvm.org/t/rfc-add-targetbuiltins-for-spirv-to-support-hlsl/83329. pattern matching will come in a separate pr this one just sets up the groundwork to do target builtins for spirv. partially resolves [#99107](#99107)
1 parent ca603d2 commit 21edac2

File tree

21 files changed

+294
-1
lines changed

21 files changed

+294
-1
lines changed

.github/new-prs-labeler.yml

+5
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,11 @@ backend:DirectX:
661661

662662
backend:SPIR-V:
663663
- clang/lib/Driver/ToolChains/SPIRV.*
664+
- clang/lib/Sema/SemaSPIRV.cpp
665+
- clang/include/clang/Sema/SemaSPIRV.h
666+
- clang/include/clang/Basic/BuiltinsSPIRV.td
667+
- clang/test/CodeGenSPIRV/**
668+
- clang/test/SemaSPIRV/**
664669
- llvm/lib/Target/SPIRV/**
665670
- llvm/test/CodeGen/SPIRV/**
666671
- llvm/test/Frontend/HLSL/**
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//===--- BuiltinsSPIRV.td - SPIRV Builtin function database ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsBase.td"
10+
11+
def HLSLDistance : Builtin {
12+
let Spellings = ["__builtin_spirv_distance"];
13+
let Attributes = [NoThrow, Const];
14+
let Prototype = "void(...)";
15+
}

clang/include/clang/Basic/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
6060
SOURCE BuiltinsRISCV.td
6161
TARGET ClangBuiltinsRISCV)
6262

63+
clang_tablegen(BuiltinsSPIRV.inc -gen-clang-builtins
64+
SOURCE BuiltinsSPIRV.td
65+
TARGET ClangBuiltinsSPIRV)
66+
6367
clang_tablegen(BuiltinsX86.inc -gen-clang-builtins
6468
SOURCE BuiltinsX86.td
6569
TARGET ClangBuiltinsX86)

clang/include/clang/Basic/TargetBuiltins.h

+10
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ namespace clang {
119119
};
120120
}
121121

122+
/// SPIRV builtins
123+
namespace SPIRV {
124+
enum {
125+
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
126+
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
127+
#include "clang/Basic/BuiltinsSPIRV.inc"
128+
LastTSBuiltin
129+
};
130+
} // namespace SPIRV
131+
122132
/// X86 builtins
123133
namespace X86 {
124134
enum {

clang/include/clang/Sema/Sema.h

+7
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class SemaOpenMP;
173173
class SemaPPC;
174174
class SemaPseudoObject;
175175
class SemaRISCV;
176+
class SemaSPIRV;
176177
class SemaSYCL;
177178
class SemaSwift;
178179
class SemaSystemZ;
@@ -1142,6 +1143,11 @@ class Sema final : public SemaBase {
11421143
return *RISCVPtr;
11431144
}
11441145

1146+
SemaSPIRV &SPIRV() {
1147+
assert(SPIRVPtr);
1148+
return *SPIRVPtr;
1149+
}
1150+
11451151
SemaSYCL &SYCL() {
11461152
assert(SYCLPtr);
11471153
return *SYCLPtr;
@@ -1219,6 +1225,7 @@ class Sema final : public SemaBase {
12191225
std::unique_ptr<SemaPPC> PPCPtr;
12201226
std::unique_ptr<SemaPseudoObject> PseudoObjectPtr;
12211227
std::unique_ptr<SemaRISCV> RISCVPtr;
1228+
std::unique_ptr<SemaSPIRV> SPIRVPtr;
12221229
std::unique_ptr<SemaSYCL> SYCLPtr;
12231230
std::unique_ptr<SemaSwift> SwiftPtr;
12241231
std::unique_ptr<SemaSystemZ> SystemZPtr;

clang/include/clang/Sema/SemaSPIRV.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----- SemaSPIRV.h ----- Semantic Analysis for SPIRV constructs--------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
/// This file declares semantic analysis for SPIRV constructs.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_SEMA_SEMASPIRV_H
14+
#define LLVM_CLANG_SEMA_SEMASPIRV_H
15+
16+
#include "clang/AST/ASTFwd.h"
17+
#include "clang/Sema/SemaBase.h"
18+
19+
namespace clang {
20+
class SemaSPIRV : public SemaBase {
21+
public:
22+
SemaSPIRV(Sema &S);
23+
24+
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
25+
};
26+
} // namespace clang
27+
28+
#endif // LLVM_CLANG_SEMA_SEMASPIRV_H

clang/lib/Basic/Targets/SPIR.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@
1313
#include "SPIR.h"
1414
#include "AMDGPU.h"
1515
#include "Targets.h"
16+
#include "clang/Basic/MacroBuilder.h"
17+
#include "clang/Basic/TargetBuiltins.h"
1618
#include "llvm/TargetParser/TargetParser.h"
1719

1820
using namespace clang;
1921
using namespace clang::targets;
2022

23+
static constexpr Builtin::Info BuiltinInfo[] = {
24+
#define BUILTIN(ID, TYPE, ATTRS) \
25+
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
26+
#include "clang/Basic/BuiltinsSPIRV.inc"
27+
};
28+
29+
ArrayRef<Builtin::Info> SPIRVTargetInfo::getTargetBuiltins() const {
30+
return llvm::ArrayRef(BuiltinInfo,
31+
clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin);
32+
}
33+
2134
void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,
2235
MacroBuilder &Builder) const {
2336
DefineStd(Builder, "SPIR", Opts);

clang/lib/Basic/Targets/SPIR.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
313313
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
314314
"v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
315315
}
316-
316+
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
317317
void getTargetDefines(const LangOptions &Opts,
318318
MacroBuilder &Builder) const override;
319319
};

clang/lib/CodeGen/CGBuiltin.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -6797,6 +6797,8 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
67976797
case llvm::Triple::riscv32:
67986798
case llvm::Triple::riscv64:
67996799
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
6800+
case llvm::Triple::spirv:
6801+
return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
68006802
case llvm::Triple::spirv64:
68016803
if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
68026804
return nullptr;
@@ -20480,6 +20482,26 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
2048020482
}
2048120483
}
2048220484

20485+
Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
20486+
const CallExpr *E) {
20487+
switch (BuiltinID) {
20488+
case SPIRV::BI__builtin_spirv_distance: {
20489+
Value *X = EmitScalarExpr(E->getArg(0));
20490+
Value *Y = EmitScalarExpr(E->getArg(1));
20491+
assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
20492+
E->getArg(1)->getType()->hasFloatingRepresentation() &&
20493+
"Distance operands must have a float representation");
20494+
assert(E->getArg(0)->getType()->isVectorType() &&
20495+
E->getArg(1)->getType()->isVectorType() &&
20496+
"Distance operands must be a vector");
20497+
return Builder.CreateIntrinsic(
20498+
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
20499+
ArrayRef<Value *>{X, Y}, nullptr, "spv.distance");
20500+
}
20501+
}
20502+
return nullptr;
20503+
}
20504+
2048320505
/// Handle a SystemZ function in which the final argument is a pointer
2048420506
/// to an int that receives the post-instruction CC value. At the LLVM level
2048520507
/// this is represented as a function that returns a {result, cc} pair.

clang/lib/CodeGen/CodeGenFunction.h

+1
Original file line numberDiff line numberDiff line change
@@ -4756,6 +4756,7 @@ class CodeGenFunction : public CodeGenTypeCache {
47564756
llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
47574757
llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
47584758
ReturnValueSlot ReturnValue);
4759+
llvm::Value *EmitSPIRVBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
47594760
llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
47604761
const CallExpr *E);
47614762
llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);

clang/lib/Sema/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ add_clang_library(clangSema
7979
SemaStmt.cpp
8080
SemaStmtAsm.cpp
8181
SemaStmtAttr.cpp
82+
SemaSPIRV.cpp
8283
SemaSYCL.cpp
8384
SemaSwift.cpp
8485
SemaSystemZ.cpp

clang/lib/Sema/Sema.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "clang/Sema/SemaPPC.h"
6262
#include "clang/Sema/SemaPseudoObject.h"
6363
#include "clang/Sema/SemaRISCV.h"
64+
#include "clang/Sema/SemaSPIRV.h"
6465
#include "clang/Sema/SemaSYCL.h"
6566
#include "clang/Sema/SemaSwift.h"
6667
#include "clang/Sema/SemaSystemZ.h"
@@ -239,6 +240,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
239240
PPCPtr(std::make_unique<SemaPPC>(*this)),
240241
PseudoObjectPtr(std::make_unique<SemaPseudoObject>(*this)),
241242
RISCVPtr(std::make_unique<SemaRISCV>(*this)),
243+
SPIRVPtr(std::make_unique<SemaSPIRV>(*this)),
242244
SYCLPtr(std::make_unique<SemaSYCL>(*this)),
243245
SwiftPtr(std::make_unique<SemaSwift>(*this)),
244246
SystemZPtr(std::make_unique<SemaSystemZ>(*this)),

clang/lib/Sema/SemaChecking.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include "clang/Sema/SemaOpenCL.h"
7171
#include "clang/Sema/SemaPPC.h"
7272
#include "clang/Sema/SemaRISCV.h"
73+
#include "clang/Sema/SemaSPIRV.h"
7374
#include "clang/Sema/SemaSystemZ.h"
7475
#include "clang/Sema/SemaWasm.h"
7576
#include "clang/Sema/SemaX86.h"
@@ -1934,6 +1935,8 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
19341935
case llvm::Triple::mips64:
19351936
case llvm::Triple::mips64el:
19361937
return MIPS().CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall);
1938+
case llvm::Triple::spirv:
1939+
return SPIRV().CheckSPIRVBuiltinFunctionCall(BuiltinID, TheCall);
19371940
case llvm::Triple::systemz:
19381941
return SystemZ().CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall);
19391942
case llvm::Triple::x86:

clang/lib/Sema/SemaSPIRV.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===- SemaSPIRV.cpp - Semantic Analysis for SPIRV constructs--------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// This implements Semantic Analysis for SPIRV constructs.
9+
//===----------------------------------------------------------------------===//
10+
11+
#include "clang/Sema/SemaSPIRV.h"
12+
#include "clang/Basic/TargetBuiltins.h"
13+
#include "clang/Sema/Sema.h"
14+
15+
namespace clang {
16+
17+
SemaSPIRV::SemaSPIRV(Sema &S) : SemaBase(S) {}
18+
19+
bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID,
20+
CallExpr *TheCall) {
21+
switch (BuiltinID) {
22+
case SPIRV::BI__builtin_spirv_distance: {
23+
if (SemaRef.checkArgCount(TheCall, 2))
24+
return true;
25+
26+
ExprResult A = TheCall->getArg(0);
27+
QualType ArgTyA = A.get()->getType();
28+
auto *VTyA = ArgTyA->getAs<VectorType>();
29+
if (VTyA == nullptr) {
30+
SemaRef.Diag(A.get()->getBeginLoc(),
31+
diag::err_typecheck_convert_incompatible)
32+
<< ArgTyA
33+
<< SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
34+
<< 0 << 0;
35+
return true;
36+
}
37+
38+
ExprResult B = TheCall->getArg(1);
39+
QualType ArgTyB = B.get()->getType();
40+
auto *VTyB = ArgTyB->getAs<VectorType>();
41+
if (VTyB == nullptr) {
42+
SemaRef.Diag(A.get()->getBeginLoc(),
43+
diag::err_typecheck_convert_incompatible)
44+
<< ArgTyB
45+
<< SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
46+
<< 0 << 0;
47+
return true;
48+
}
49+
50+
QualType RetTy = VTyA->getElementType();
51+
TheCall->setType(RetTy);
52+
break;
53+
}
54+
}
55+
return false;
56+
}
57+
} // namespace clang
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
3+
// RUN: %clang_cc1 -O1 -triple spirv-pc-vulkan-compute %s -emit-llvm -o - | FileCheck %s
4+
5+
typedef float float2 __attribute__((ext_vector_type(2)));
6+
typedef float float3 __attribute__((ext_vector_type(3)));
7+
typedef float float4 __attribute__((ext_vector_type(4)));
8+
9+
// CHECK-LABEL: define spir_func float @test_distance_float2(
10+
// CHECK-SAME: <2 x float> noundef [[X:%.*]], <2 x float> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
11+
// CHECK-NEXT: [[ENTRY:.*:]]
12+
// CHECK-NEXT: [[SPV_DISTANCE:%.*]] = tail call float @llvm.spv.distance.v2f32(<2 x float> [[X]], <2 x float> [[Y]])
13+
// CHECK-NEXT: ret float [[SPV_DISTANCE]]
14+
//
15+
float test_distance_float2(float2 X, float2 Y) { return __builtin_spirv_distance(X, Y); }
16+
17+
// CHECK-LABEL: define spir_func float @test_distance_float3(
18+
// CHECK-SAME: <3 x float> noundef [[X:%.*]], <3 x float> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
19+
// CHECK-NEXT: [[ENTRY:.*:]]
20+
// CHECK-NEXT: [[SPV_DISTANCE:%.*]] = tail call float @llvm.spv.distance.v3f32(<3 x float> [[X]], <3 x float> [[Y]])
21+
// CHECK-NEXT: ret float [[SPV_DISTANCE]]
22+
//
23+
float test_distance_float3(float3 X, float3 Y) { return __builtin_spirv_distance(X, Y); }
24+
25+
// CHECK-LABEL: define spir_func float @test_distance_float4(
26+
// CHECK-SAME: <4 x float> noundef [[X:%.*]], <4 x float> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
27+
// CHECK-NEXT: [[ENTRY:.*:]]
28+
// CHECK-NEXT: [[SPV_DISTANCE:%.*]] = tail call float @llvm.spv.distance.v4f32(<4 x float> [[X]], <4 x float> [[Y]])
29+
// CHECK-NEXT: ret float [[SPV_DISTANCE]]
30+
//
31+
float test_distance_float4(float4 X, float4 Y) { return __builtin_spirv_distance(X, Y); }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 %s -triple spirv-pc-vulkan-compute -verify
2+
3+
typedef float float2 __attribute__((ext_vector_type(2)));
4+
5+
float test_no_second_arg(float2 p0) {
6+
return __builtin_spirv_distance(p0);
7+
// expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
8+
}
9+
10+
float test_too_many_arg(float2 p0) {
11+
return __builtin_spirv_distance(p0, p0, p0);
12+
// expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
13+
}
14+
15+
float test_double_scalar_inputs(double p0, double p1) {
16+
return __builtin_spirv_distance(p0, p1);
17+
// expected-error@-1 {{passing 'double' to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(double)))) double' (vector of 2 'double' values)}}
18+
}
19+
20+
float test_int_scalar_inputs(int p0, int p1) {
21+
return __builtin_spirv_distance(p0, p1);
22+
// expected-error@-1 {{passing 'int' to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
23+
}

llvm/include/llvm/IR/IntrinsicsSPIRV.td

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ let TargetPrefix = "spv" in {
6565
def int_spv_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
6666
def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
6767
def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
68+
def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
6869
def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
6970
def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
7071
[IntrNoMem] >;

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2914,6 +2914,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
29142914
return selectAny(ResVReg, ResType, I);
29152915
case Intrinsic::spv_cross:
29162916
return selectExtInst(ResVReg, ResType, I, CL::cross, GL::Cross);
2917+
case Intrinsic::spv_distance:
2918+
return selectExtInst(ResVReg, ResType, I, CL::distance, GL::Distance);
29172919
case Intrinsic::spv_lerp:
29182920
return selectExtInst(ResVReg, ResType, I, CL::mix, GL::FMix);
29192921
case Intrinsic::spv_length:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; Make sure SPIRV operation function calls for distance are lowered correctly.
5+
6+
; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
7+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
8+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
9+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
10+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
11+
12+
define noundef half @distance_half4(<4 x half> noundef %a, <4 x half> noundef %b) {
13+
entry:
14+
; CHECK: %[[#]] = OpFunction %[[#float_16]] None %[[#]]
15+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
16+
; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
17+
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Distance %[[#arg0]] %[[#arg1]]
18+
%spv.distance = call half @llvm.spv.distance.f16(<4 x half> %a, <4 x half> %b)
19+
ret half %spv.distance
20+
}
21+
22+
define noundef float @distance_float4(<4 x float> noundef %a, <4 x float> noundef %b) {
23+
entry:
24+
; CHECK: %[[#]] = OpFunction %[[#float_32]] None %[[#]]
25+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
26+
; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
27+
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Distance %[[#arg0]] %[[#arg1]]
28+
%spv.distance = call float @llvm.spv.distance.f32(<4 x float> %a, <4 x float> %b)
29+
ret float %spv.distance
30+
}
31+
32+
declare half @llvm.spv.distance.f16(<4 x half>, <4 x half>)
33+
declare float @llvm.spv.distance.f32(<4 x float>, <4 x float>)

0 commit comments

Comments
 (0)