Skip to content

[HLSL] Implement the degrees intrinsic #111209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4745,6 +4745,12 @@ def HLSLCross: LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLDegrees : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_degrees"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_dot"];
let Attributes = [NoThrow, Const];
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18755,6 +18755,16 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
CGM.getHLSLRuntime().getNormalizeIntrinsic(), ArrayRef<Value *>{X},
nullptr, "hlsl.normalize");
}
case Builtin::BI__builtin_hlsl_elementwise_degrees: {
Value *X = EmitScalarExpr(E->getArg(0));

assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
"degree operand must have a float representation");

return Builder.CreateIntrinsic(
/*ReturnType=*/X->getType(), CGM.getHLSLRuntime().getDegreesIntrinsic(),
ArrayRef<Value *>{X}, nullptr, "hlsl.degrees");
}
case Builtin::BI__builtin_hlsl_elementwise_frac: {
Value *Op0 = EmitScalarExpr(E->getArg(0));
if (!E->getArg(0)->getType()->hasFloatingRepresentation())
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(All, all)
GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any)
GENERATE_HLSL_INTRINSIC_FUNCTION(Cross, cross)
GENERATE_HLSL_INTRINSIC_FUNCTION(Degrees, degrees)
GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac)
GENERATE_HLSL_INTRINSIC_FUNCTION(Length, length)
GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp)
Expand Down
30 changes: 30 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,36 @@ uint64_t3 countbits(uint64_t3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
uint64_t4 countbits(uint64_t4);

//===----------------------------------------------------------------------===//
// degrees builtins
//===----------------------------------------------------------------------===//

/// \fn T degrees(T x)
/// \brief Converts the specified value from radians to degrees.
/// \param x The specified input value.

_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
half degrees(half);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
half2 degrees(half2);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
half3 degrees(half3);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
half4 degrees(half4);

_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
float degrees(float);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
float2 degrees(float2);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
float3 degrees(float3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
float4 degrees(float4);

//===----------------------------------------------------------------------===//
// dot product builtins
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return true;
break;
}
case Builtin::BI__builtin_hlsl_elementwise_degrees:
case Builtin::BI__builtin_hlsl_elementwise_radians:
case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
case Builtin::BI__builtin_hlsl_elementwise_frac: {
Expand Down
64 changes: 64 additions & 0 deletions clang/test/CodeGenHLSL/builtins/degrees.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: %clang_cc1 -finclude-default-header -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
// RUN: %clang_cc1 -finclude-default-header -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv

// NATIVE_HALF: define [[FNATTRS]] half @
// NATIVE_HALF: %hlsl.degrees = call half @llvm.[[TARGET]].degrees.f16(
// NATIVE_HALF: ret half %hlsl.degrees
// NO_HALF: define [[FNATTRS]] float @
// NO_HALF: %hlsl.degrees = call float @llvm.[[TARGET]].degrees.f32(
// NO_HALF: ret float %hlsl.degrees
half test_degrees_half(half p0) { return degrees(p0); }
// NATIVE_HALF: define [[FNATTRS]] <2 x half> @
// NATIVE_HALF: %hlsl.degrees = call <2 x half> @llvm.[[TARGET]].degrees.v2f16
// NATIVE_HALF: ret <2 x half> %hlsl.degrees
// NO_HALF: define [[FNATTRS]] <2 x float> @
// NO_HALF: %hlsl.degrees = call <2 x float> @llvm.[[TARGET]].degrees.v2f32(
// NO_HALF: ret <2 x float> %hlsl.degrees
half2 test_degrees_half2(half2 p0) { return degrees(p0); }
// NATIVE_HALF: define [[FNATTRS]] <3 x half> @
// NATIVE_HALF: %hlsl.degrees = call <3 x half> @llvm.[[TARGET]].degrees.v3f16
// NATIVE_HALF: ret <3 x half> %hlsl.degrees
// NO_HALF: define [[FNATTRS]] <3 x float> @
// NO_HALF: %hlsl.degrees = call <3 x float> @llvm.[[TARGET]].degrees.v3f32(
// NO_HALF: ret <3 x float> %hlsl.degrees
half3 test_degrees_half3(half3 p0) { return degrees(p0); }
// NATIVE_HALF: define [[FNATTRS]] <4 x half> @
// NATIVE_HALF: %hlsl.degrees = call <4 x half> @llvm.[[TARGET]].degrees.v4f16
// NATIVE_HALF: ret <4 x half> %hlsl.degrees
// NO_HALF: define [[FNATTRS]] <4 x float> @
// NO_HALF: %hlsl.degrees = call <4 x float> @llvm.[[TARGET]].degrees.v4f32(
// NO_HALF: ret <4 x float> %hlsl.degrees
half4 test_degrees_half4(half4 p0) { return degrees(p0); }

// CHECK: define [[FNATTRS]] float @
// CHECK: %hlsl.degrees = call float @llvm.[[TARGET]].degrees.f32(
// CHECK: ret float %hlsl.degrees
float test_degrees_float(float p0) { return degrees(p0); }
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %hlsl.degrees = call <2 x float> @llvm.[[TARGET]].degrees.v2f32
// CHECK: ret <2 x float> %hlsl.degrees
float2 test_degrees_float2(float2 p0) { return degrees(p0); }
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %hlsl.degrees = call <3 x float> @llvm.[[TARGET]].degrees.v3f32
// CHECK: ret <3 x float> %hlsl.degrees
float3 test_degrees_float3(float3 p0) { return degrees(p0); }
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %hlsl.degrees = call <4 x float> @llvm.[[TARGET]].degrees.v4f32
// CHECK: ret <4 x float> %hlsl.degrees
float4 test_degrees_float4(float4 p0) { return degrees(p0); }
26 changes: 26 additions & 0 deletions clang/test/SemaHLSL/BuiltIns/degrees-errors.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify

float test_too_few_arg() {
return __builtin_hlsl_elementwise_degrees();
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
}

float2 test_too_many_arg(float2 p0) {
return __builtin_hlsl_elementwise_degrees(p0, p0);
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
}

float builtin_bool_to_float_type_promotion(bool p1) {
return __builtin_hlsl_elementwise_degrees(p1);
// expected-error@-1 {{passing 'bool' to parameter of incompatible type 'float'}}
}

float builtin_degrees_int_to_float_promotion(int p1) {
return __builtin_hlsl_elementwise_degrees(p1);
// expected-error@-1 {{passing 'int' to parameter of incompatible type 'float'}}
}

float2 builtin_degrees_int2_to_float2_promotion(int2 p1) {
return __builtin_hlsl_elementwise_degrees(p1);
// expected-error@-1 {{passing 'int2' (aka 'vector<int, 2>') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}}
}
1 change: 1 addition & 0 deletions clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_tan
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_tanh
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_elementwise_trunc
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_hlsl_elementwise_degrees
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -DTEST_FUNC=__builtin_hlsl_elementwise_radians

double test_double_builtin(double p0) {
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def int_dx_udot :
[IntrNoMem, Commutative] >;

def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;

def int_dx_isinf : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[llvm_anyfloat_ty], [IntrNoMem]>;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/IntrinsicsSPIRV.td
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ let TargetPrefix = "spv" in {
def int_spv_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
def int_spv_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
[IntrNoMem] >;
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static bool isIntrinsicExpansion(Function &F) {
case Intrinsic::dx_clamp:
case Intrinsic::dx_cross:
case Intrinsic::dx_uclamp:
case Intrinsic::dx_degrees:
case Intrinsic::dx_lerp:
case Intrinsic::dx_length:
case Intrinsic::dx_normalize:
Expand Down Expand Up @@ -490,6 +491,14 @@ static Value *expandClampIntrinsic(CallInst *Orig,
{MaxCall, Max}, nullptr, "dx.min");
}

static Value *expandDegreesIntrinsic(CallInst *Orig) {
Value *X = Orig->getOperand(0);
Type *Ty = X->getType();
IRBuilder<> Builder(Orig);
Value *DegreesRatio = ConstantFP::get(Ty, 180.0 * llvm::numbers::inv_pi);
return Builder.CreateFMul(X, DegreesRatio);
}

static Value *expandSignIntrinsic(CallInst *Orig) {
Value *X = Orig->getOperand(0);
Type *Ty = X->getType();
Expand Down Expand Up @@ -549,6 +558,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
case Intrinsic::dx_clamp:
Result = expandClampIntrinsic(Orig, IntrinsicId);
break;
case Intrinsic::dx_degrees:
Result = expandDegreesIntrinsic(Orig);
break;
case Intrinsic::dx_lerp:
Result = expandLerpIntrinsic(Orig);
break;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
return selectExtInst(ResVReg, ResType, I, CL::mix, GL::FMix);
case Intrinsic::spv_length:
return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
case Intrinsic::spv_degrees:
return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
case Intrinsic::spv_frac:
return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
case Intrinsic::spv_normalize:
Expand Down
54 changes: 54 additions & 0 deletions llvm/test/CodeGen/DirectX/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s

; Make sure dxil op function calls for degrees are expanded and lowered as fmul for float and half.

define noundef half @degrees_half(half noundef %a) {
; CHECK-LABEL: define noundef half @degrees_half(
; CHECK-SAME: half noundef [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[DX_DEGREES1:%.*]] = fmul half [[A]], 0xH5329
; CHECK-NEXT: ret half [[DX_DEGREES1]]
;
entry:
%dx.degrees = call half @llvm.dx.degrees.f16(half %a)
ret half %dx.degrees
}

define noundef float @degrees_float(float noundef %a) #0 {
; CHECK-LABEL: define noundef float @degrees_float(
; CHECK-SAME: float noundef [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[DEGREES:%.*]] = fmul float [[A]], 0x404CA5DC20000000
; CHECK-NEXT: ret float [[DEGREES]]
;
entry:
%dx.degrees = call float @llvm.dx.degrees.f32(float %a)
ret float %dx.degrees
}

define noundef <4 x float> @degrees_float4(<4 x float> noundef %a) #0 {
; CHECK-LABEL: define noundef <4 x float> @degrees_float4(
; CHECK-SAME: <4 x float> noundef [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A]], i64 0
; CHECK-NEXT: [[DEGREES_A0:%.*]] = fmul float [[A0]], 0x404CA5DC20000000
; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i64 1
; CHECK-NEXT: [[DEGREES_A1:%.*]] = fmul float [[A1]], 0x404CA5DC20000000
; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i64 2
; CHECK-NEXT: [[DEGREES_A2:%.*]] = fmul float [[A2]], 0x404CA5DC20000000
; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i64 3
; CHECK-NEXT: [[DEGREES_A3:%.*]] = fmul float [[A3]], 0x404CA5DC20000000
; CHECK-NEXT: [[INSERT_0:%.*]] = insertelement <4 x float> poison, float [[DEGREES_A0]], i64 0
; CHECK-NEXT: [[INSERT_1:%.*]] = insertelement <4 x float> [[INSERT_0]], float [[DEGREES_A1]], i64 1
; CHECK-NEXT: [[INSERT_2:%.*]] = insertelement <4 x float> [[INSERT_1]], float [[DEGREES_A2]], i64 2
; CHECK-NEXT: [[RES:%.*]] = insertelement <4 x float> [[INSERT_2]], float [[DEGREES_A3]], i64 3
; CHECK-NEXT: ret <4 x float> [[RES]]
;
entry:
%2 = call <4 x float> @llvm.dx.degrees.v4f32(<4 x float> %a)
ret <4 x float> %2
}

declare half @llvm.dx.degrees.f16(half)
declare float @llvm.dx.degrees.f32(float)
declare <4 x float> @llvm.dx.degrees.v4f32(<4 x float>)
52 changes: 52 additions & 0 deletions llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"

; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16

; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4

; CHECK-LABEL: Begin function degrees_float
define noundef float @degrees_float(float noundef %a) {
entry:
; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Degrees %[[#float_32_arg]]
%elt.degrees = call float @llvm.spv.degrees.f32(float %a)
ret float %elt.degrees
}

; CHECK-LABEL: Begin function degrees_half
define noundef half @degrees_half(half noundef %a) {
entry:
; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Degrees %[[#float_16_arg]]
%elt.degrees = call half @llvm.spv.degrees.f16(half %a)
ret half %elt.degrees
}

; CHECK-LABEL: Begin function degrees_float_vector
define noundef <4 x float> @degrees_float_vector(<4 x float> noundef %a) {
entry:
; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Degrees %[[#vec4_float_32_arg]]
%elt.degrees = call <4 x float> @llvm.spv.degrees.v4f32(<4 x float> %a)
ret <4 x float> %elt.degrees
}

; CHECK-LABEL: Begin function degrees_half_vector
define noundef <4 x half> @degrees_half_vector(<4 x half> noundef %a) {
entry:
; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Degrees %[[#vec4_float_16_arg]]
%elt.degrees = call <4 x half> @llvm.spv.degrees.v4f16(<4 x half> %a)
ret <4 x half> %elt.degrees
}

declare half @llvm.spv.degrees.f16(half)
declare float @llvm.spv.degrees.f32(float)

declare <4 x float> @llvm.spv.degrees.v4f32(<4 x float>)
declare <4 x half> @llvm.spv.degrees.v4f16(<4 x half>)
50 changes: 50 additions & 0 deletions llvm/test/CodeGen/SPIRV/opencl/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "OpenCL.std"

; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16

; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4

declare half @llvm.spv.degrees.f16(half)
declare float @llvm.spv.degrees.f32(float)

declare <4 x float> @llvm.spv.degrees.v4f32(<4 x float>)
declare <4 x half> @llvm.spv.degrees.v4f16(<4 x half>)

define noundef float @degrees_float(float noundef %a) {
entry:
; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] degrees %[[#float_32_arg]]
%elt.degrees = call float @llvm.spv.degrees.f32(float %a)
ret float %elt.degrees
}

define noundef half @degrees_half(half noundef %a) {
entry:
; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] degrees %[[#float_16_arg]]
%elt.degrees = call half @llvm.spv.degrees.f16(half %a)
ret half %elt.degrees
}

define noundef <4 x float> @degrees_float_vector(<4 x float> noundef %a) {
entry:
; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] degrees %[[#vec4_float_32_arg]]
%elt.degrees = call <4 x float> @llvm.spv.degrees.v4f32(<4 x float> %a)
ret <4 x float> %elt.degrees
}

define noundef <4 x half> @degrees_half_vector(<4 x half> noundef %a) {
entry:
; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] degrees %[[#vec4_float_16_arg]]
%elt.degrees = call <4 x half> @llvm.spv.degrees.v4f16(<4 x half> %a)
ret <4 x half> %elt.degrees
}
Loading