https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/111209
>From 398dcb5c1a354c12d4d43af152f6d3e14f001274 Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Wed, 2 Oct 2024 13:30:33 -0700 Subject: [PATCH] [HLSL] Implementation the `degrees` intrinsic - add degrees builtin - link degrees api in hlsl_intrinsics.h - add degrees intrinsic to IntrinsicDirectX.td - add degrees intrinsic to IntrinsicSPIRV.td - add lowering from clang builtin to dx/spv intrinsics in CGBuiltin.cpp - add semantic checks to SemaHLSL.cpp - add expansion of directx intrinsic to llvm fmul for DirectX in DXILIntrinsicExpansion.cpp - add mapping to spir-v intrinsic in SPIRVInstructionSelector.cpp - add test coverage: - degrees.hlsl -> check hlsl lowering to dx/spv degrees intrinsics - degrees-errors.hlsl/half-float-only-errors -> check semantic warnings - hlsl-intrinsics/degrees.ll -> check lowering of spir-v degrees intrinsic to SPIR-V backend - DirectX/degrees.ll -> check expansion and scalarization of directx degrees intrinsic to fmul --- clang/include/clang/Basic/Builtins.td | 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 11 +++ clang/lib/CodeGen/CGHLSLRuntime.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 30 ++++++++ clang/lib/Sema/SemaHLSL.cpp | 1 + clang/test/CodeGenHLSL/builtins/degrees.hlsl | 64 +++++++++++++++++ .../SemaHLSL/BuiltIns/degrees-errors.hlsl | 26 +++++++ .../BuiltIns/half-float-only-errors.hlsl | 1 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 12 ++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 + llvm/test/CodeGen/DirectX/degrees.ll | 54 +++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/degrees.ll | 68 +++++++++++++++++++ llvm/test/CodeGen/SPIRV/opencl/degrees.ll | 50 ++++++++++++++ 15 files changed, 328 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/degrees.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/degrees-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/degrees.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll create mode 100644 llvm/test/CodeGen/SPIRV/opencl/degrees.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 5b504666365b32..44142298987f12 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4739,6 +4739,12 @@ def HLSLClamp : 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]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index c864714182e019..0f824fc2c4431a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18740,6 +18740,17 @@ 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()) diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index a8aabca7348ffb..966111a9600017 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -74,6 +74,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(All, all) GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any) + GENERATE_HLSL_INTRINSIC_FUNCTION(Degrees, degrees) GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac) GENERATE_HLSL_INTRINSIC_FUNCTION(Length, length) GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index d28f204e352de5..07004a48f96128 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -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 //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 5eda22f560c9d2..7e971e9fc92e05 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1861,6 +1861,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_elementwise_degrees: case Builtin::BI__builtin_hlsl_elementwise_rsqrt: case Builtin::BI__builtin_hlsl_elementwise_frac: { if (CheckFloatOrHalfRepresentations(&SemaRef, TheCall)) diff --git a/clang/test/CodeGenHLSL/builtins/degrees.hlsl b/clang/test/CodeGenHLSL/builtins/degrees.hlsl new file mode 100644 index 00000000000000..b861be2e79fa2c --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/degrees.hlsl @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -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 -x hlsl -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 -x hlsl -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 -x hlsl -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); } diff --git a/clang/test/SemaHLSL/BuiltIns/degrees-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/degrees-errors.hlsl new file mode 100644 index 00000000000000..e39ffda4696940 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/degrees-errors.hlsl @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected + +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)}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl index 0c1f7022bad609..c12a230ea6f4eb 100644 --- a/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl @@ -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 double test_double_builtin(double p0) { return TEST_FUNC(p0); diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index 81d7e55047c77c..caacb65ac18837 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -70,6 +70,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]>; diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index efe19f5a8370e5..ee61793bbea241 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -61,6 +61,7 @@ let TargetPrefix = "spv" in { def int_spv_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>; 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_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] >; diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index fca5af9d19141e..0cb0dc4c48e541 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -55,6 +55,7 @@ static bool isIntrinsicExpansion(Function &F) { case Intrinsic::dx_any: case Intrinsic::dx_clamp: case Intrinsic::dx_uclamp: + case Intrinsic::dx_degrees: case Intrinsic::dx_lerp: case Intrinsic::dx_length: case Intrinsic::dx_normalize: @@ -444,6 +445,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(); @@ -500,6 +509,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; diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index c1a0cd9837d146..103103050d412c 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -2504,6 +2504,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: diff --git a/llvm/test/CodeGen/DirectX/degrees.ll b/llvm/test/CodeGen/DirectX/degrees.ll new file mode 100644 index 00000000000000..3cc4edadaa5e93 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/degrees.ll @@ -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: [[DX_DEGREES1:%.*]] = fmul float [[A]], 0x404CA5DC20000000 +; CHECK-NEXT: ret float [[DX_DEGREES1]] +; +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: [[A_I0:%.*]] = extractelement <4 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI04:%.*]] = fmul float [[A_I0]], 0x404CA5DC20000000 +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <4 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI13:%.*]] = fmul float [[A_I1]], 0x404CA5DC20000000 +; CHECK-NEXT: [[A_I2:%.*]] = extractelement <4 x float> [[A]], i64 2 +; CHECK-NEXT: [[DOTI22:%.*]] = fmul float [[A_I2]], 0x404CA5DC20000000 +; CHECK-NEXT: [[A_I3:%.*]] = extractelement <4 x float> [[A]], i64 3 +; CHECK-NEXT: [[DOTI31:%.*]] = fmul float [[A_I3]], 0x404CA5DC20000000 +; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <4 x float> poison, float [[DOTI04]], i64 0 +; CHECK-NEXT: [[DOTUPTO1:%.*]] = insertelement <4 x float> [[DOTUPTO0]], float [[DOTI13]], i64 1 +; CHECK-NEXT: [[DOTUPTO2:%.*]] = insertelement <4 x float> [[DOTUPTO1]], float [[DOTI22]], i64 2 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x float> [[DOTUPTO2]], float [[DOTI31]], i64 3 +; CHECK-NEXT: ret <4 x float> [[TMP0]] +; +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>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll new file mode 100644 index 00000000000000..ce648e0e51ba2c --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll @@ -0,0 +1,68 @@ +; 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: %[[#float_64:]] = OpTypeFloat 64 + +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 +; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4 + +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 double @degrees_double(double noundef %a) { +entry: +; CHECK: %[[#float_64_arg:]] = OpFunctionParameter %[[#float_64]] +; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext_glsl]] Degrees %[[#float_64_arg]] + %elt.degrees = call double @llvm.spv.degrees.f64(double %a) + ret double %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 +} + +define noundef <4 x double> @degrees_double_vector(<4 x double> noundef %a) { +entry: +; CHECK: %[[#vec4_float_64_arg:]] = OpFunctionParameter %[[#vec4_float_64]] +; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext_glsl]] Degrees %[[#vec4_float_64_arg]] + %elt.degrees = call <4 x double> @llvm.spv.degrees.v4f64(<4 x double> %a) + ret <4 x double> %elt.degrees +} + +declare half @llvm.spv.degrees.f16(half) +declare float @llvm.spv.degrees.f32(float) +declare double @llvm.spv.degrees.f64(double) + +declare <4 x float> @llvm.spv.degrees.v4f32(<4 x float>) +declare <4 x half> @llvm.spv.degrees.v4f16(<4 x half>) +declare <4 x double> @llvm.spv.degrees.v4f64(<4 x double>) diff --git a/llvm/test/CodeGen/SPIRV/opencl/degrees.ll b/llvm/test/CodeGen/SPIRV/opencl/degrees.ll new file mode 100644 index 00000000000000..88f97835fe7194 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/opencl/degrees.ll @@ -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 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits