Skip to content

Commit 04fa155

Browse files
committed
[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
1 parent f3c408d commit 04fa155

File tree

14 files changed

+309
-0
lines changed

14 files changed

+309
-0
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4709,6 +4709,12 @@ def HLSLClamp : LangBuiltin<"HLSL_LANG"> {
47094709
let Prototype = "void(...)";
47104710
}
47114711

4712+
def HLSLDegrees : LangBuiltin<"HLSL_LANG"> {
4713+
let Spellings = ["__builtin_hlsl_elementwise_degrees"];
4714+
let Attributes = [NoThrow, Const];
4715+
let Prototype = "void(...)";
4716+
}
4717+
47124718
def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
47134719
let Spellings = ["__builtin_hlsl_dot"];
47144720
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18715,6 +18715,17 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1871518715
CGM.getHLSLRuntime().getNormalizeIntrinsic(), ArrayRef<Value *>{X},
1871618716
nullptr, "hlsl.normalize");
1871718717
}
18718+
case Builtin::BI__builtin_hlsl_elementwise_degrees: {
18719+
Value *X = EmitScalarExpr(E->getArg(0));
18720+
18721+
assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
18722+
"degree operand must have a float representation");
18723+
18724+
return Builder.CreateIntrinsic(
18725+
/*ReturnType=*/X->getType(),
18726+
CGM.getHLSLRuntime().getDegreesIntrinsic(),
18727+
ArrayRef<Value *>{X}, nullptr, "hlsl.degrees");
18728+
}
1871818729
case Builtin::BI__builtin_hlsl_elementwise_frac: {
1871918730
Value *Op0 = EmitScalarExpr(E->getArg(0));
1872018731
if (!E->getArg(0)->getType()->hasFloatingRepresentation())

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class CGHLSLRuntime {
7474

7575
GENERATE_HLSL_INTRINSIC_FUNCTION(All, all)
7676
GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any)
77+
GENERATE_HLSL_INTRINSIC_FUNCTION(Degrees, degrees)
7778
GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac)
7879
GENERATE_HLSL_INTRINSIC_FUNCTION(Length, length)
7980
GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp)

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,36 @@ uint64_t3 countbits(uint64_t3);
736736
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
737737
uint64_t4 countbits(uint64_t4);
738738

739+
//===----------------------------------------------------------------------===//
740+
// degrees builtins
741+
//===----------------------------------------------------------------------===//
742+
743+
/// \fn T degrees(T x)
744+
/// \brief Converts the specified value from radians to degrees.
745+
/// \param x The specified input value.
746+
747+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
748+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
749+
half degrees(half);
750+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
751+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
752+
half2 degrees(half2);
753+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
754+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
755+
half3 degrees(half3);
756+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
757+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
758+
half4 degrees(half4);
759+
760+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
761+
float degrees(float);
762+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
763+
float2 degrees(float2);
764+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
765+
float3 degrees(float3);
766+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
767+
float4 degrees(float4);
768+
739769
//===----------------------------------------------------------------------===//
740770
// dot product builtins
741771
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
18611861
return true;
18621862
break;
18631863
}
1864+
case Builtin::BI__builtin_hlsl_elementwise_degrees:
18641865
case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
18651866
case Builtin::BI__builtin_hlsl_elementwise_frac: {
18661867
if (CheckFloatOrHalfRepresentations(&SemaRef, TheCall))
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
2+
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3+
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
4+
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
5+
// RUN: -DFNATTRS=noundef -DTARGET=dx
6+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
7+
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
8+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
9+
// RUN: -DFNATTRS=noundef -DTARGET=dx
10+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
11+
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
12+
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
13+
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
14+
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
15+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
16+
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
17+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
18+
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
19+
20+
// NATIVE_HALF: define [[FNATTRS]] half @
21+
// NATIVE_HALF: %hlsl.degrees = call half @llvm.[[TARGET]].degrees.f16(
22+
// NATIVE_HALF: ret half %hlsl.degrees
23+
// NO_HALF: define [[FNATTRS]] float @
24+
// NO_HALF: %hlsl.degrees = call float @llvm.[[TARGET]].degrees.f32(
25+
// NO_HALF: ret float %hlsl.degrees
26+
half test_degrees_half(half p0) { return degrees(p0); }
27+
// NATIVE_HALF: define [[FNATTRS]] <2 x half> @
28+
// NATIVE_HALF: %hlsl.degrees = call <2 x half> @llvm.[[TARGET]].degrees.v2f16
29+
// NATIVE_HALF: ret <2 x half> %hlsl.degrees
30+
// NO_HALF: define [[FNATTRS]] <2 x float> @
31+
// NO_HALF: %hlsl.degrees = call <2 x float> @llvm.[[TARGET]].degrees.v2f32(
32+
// NO_HALF: ret <2 x float> %hlsl.degrees
33+
half2 test_degrees_half2(half2 p0) { return degrees(p0); }
34+
// NATIVE_HALF: define [[FNATTRS]] <3 x half> @
35+
// NATIVE_HALF: %hlsl.degrees = call <3 x half> @llvm.[[TARGET]].degrees.v3f16
36+
// NATIVE_HALF: ret <3 x half> %hlsl.degrees
37+
// NO_HALF: define [[FNATTRS]] <3 x float> @
38+
// NO_HALF: %hlsl.degrees = call <3 x float> @llvm.[[TARGET]].degrees.v3f32(
39+
// NO_HALF: ret <3 x float> %hlsl.degrees
40+
half3 test_degrees_half3(half3 p0) { return degrees(p0); }
41+
// NATIVE_HALF: define [[FNATTRS]] <4 x half> @
42+
// NATIVE_HALF: %hlsl.degrees = call <4 x half> @llvm.[[TARGET]].degrees.v4f16
43+
// NATIVE_HALF: ret <4 x half> %hlsl.degrees
44+
// NO_HALF: define [[FNATTRS]] <4 x float> @
45+
// NO_HALF: %hlsl.degrees = call <4 x float> @llvm.[[TARGET]].degrees.v4f32(
46+
// NO_HALF: ret <4 x float> %hlsl.degrees
47+
half4 test_degrees_half4(half4 p0) { return degrees(p0); }
48+
49+
// CHECK: define [[FNATTRS]] float @
50+
// CHECK: %hlsl.degrees = call float @llvm.[[TARGET]].degrees.f32(
51+
// CHECK: ret float %hlsl.degrees
52+
float test_degrees_float(float p0) { return degrees(p0); }
53+
// CHECK: define [[FNATTRS]] <2 x float> @
54+
// CHECK: %hlsl.degrees = call <2 x float> @llvm.[[TARGET]].degrees.v2f32
55+
// CHECK: ret <2 x float> %hlsl.degrees
56+
float2 test_degrees_float2(float2 p0) { return degrees(p0); }
57+
// CHECK: define [[FNATTRS]] <3 x float> @
58+
// CHECK: %hlsl.degrees = call <3 x float> @llvm.[[TARGET]].degrees.v3f32
59+
// CHECK: ret <3 x float> %hlsl.degrees
60+
float3 test_degrees_float3(float3 p0) { return degrees(p0); }
61+
// CHECK: define [[FNATTRS]] <4 x float> @
62+
// CHECK: %hlsl.degrees = call <4 x float> @llvm.[[TARGET]].degrees.v4f32
63+
// CHECK: ret <4 x float> %hlsl.degrees
64+
float4 test_degrees_float4(float4 p0) { return degrees(p0); }
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// 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
2+
3+
float test_too_few_arg() {
4+
return __builtin_hlsl_elementwise_degrees();
5+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
6+
}
7+
8+
float2 test_too_many_arg(float2 p0) {
9+
return __builtin_hlsl_elementwise_degrees(p0, p0);
10+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
11+
}
12+
13+
float builtin_bool_to_float_type_promotion(bool p1) {
14+
return __builtin_hlsl_elementwise_degrees(p1);
15+
// expected-error@-1 {{passing 'bool' to parameter of incompatible type 'float'}}
16+
}
17+
18+
float builtin_degrees_int_to_float_promotion(int p1) {
19+
return __builtin_hlsl_elementwise_degrees(p1);
20+
// expected-error@-1 {{passing 'int' to parameter of incompatible type 'float'}}
21+
}
22+
23+
float2 builtin_degrees_int2_to_float2_promotion(int2 p1) {
24+
return __builtin_hlsl_elementwise_degrees(p1);
25+
// 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)}}
26+
}
27+
28+
// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion
29+
half builtin_degrees_half_scalar (half p0) {
30+
return __builtin_hlsl_elementwise_degrees(p0);
31+
// expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}}
32+
}
33+
34+
float builtin_degrees_float_scalar (float p0) {
35+
return __builtin_hlsl_elementwise_degrees(p0);
36+
// expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}}
37+
}

clang/test/SemaHLSL/BuiltIns/half-float-only-errors.hlsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// 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
1818
// 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
1919
// 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
20+
// 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
2021

2122
double2 test_double_builtin(double2 p0) {
2223
return TEST_FUNC(p0);

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def int_dx_udot :
7070
[IntrNoMem, Commutative] >;
7171

7272
def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
73+
def int_dx_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>;
7374

7475
def int_dx_isinf : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
7576
[llvm_anyfloat_ty], [IntrNoMem]>;

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ let TargetPrefix = "spv" in {
6161
def int_spv_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
6262
def int_spv_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
6363
def int_spv_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
64+
def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>;
6465
def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>;
6566
def int_spv_lerp : Intrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
6667
[IntrNoMem, IntrWillReturn] >;

llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static bool isIntrinsicExpansion(Function &F) {
4545
case Intrinsic::dx_any:
4646
case Intrinsic::dx_clamp:
4747
case Intrinsic::dx_uclamp:
48+
case Intrinsic::dx_degrees:
4849
case Intrinsic::dx_lerp:
4950
case Intrinsic::dx_length:
5051
case Intrinsic::dx_normalize:
@@ -434,6 +435,14 @@ static Value *expandClampIntrinsic(CallInst *Orig,
434435
{MaxCall, Max}, nullptr, "dx.min");
435436
}
436437

438+
static Value *expandDegreesIntrinsic(CallInst *Orig) {
439+
Value *X = Orig->getOperand(0);
440+
Type *Ty = X->getType();
441+
IRBuilder<> Builder(Orig);
442+
Value *DegreesRatio = ConstantFP::get(Ty, 180.0 * llvm::numbers::inv_pi);
443+
return Builder.CreateFMul(X, DegreesRatio);
444+
}
445+
437446
static Value *expandSignIntrinsic(CallInst *Orig) {
438447
Value *X = Orig->getOperand(0);
439448
Type *Ty = X->getType();
@@ -490,6 +499,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
490499
case Intrinsic::dx_clamp:
491500
Result = expandClampIntrinsic(Orig, IntrinsicId);
492501
break;
502+
case Intrinsic::dx_degrees:
503+
Result = expandDegreesIntrinsic(Orig);
504+
break;
493505
case Intrinsic::dx_lerp:
494506
Result = expandLerpIntrinsic(Orig);
495507
break;

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
157157
bool selectLength(Register ResVReg, const SPIRVType *ResType,
158158
MachineInstr &I) const;
159159

160+
bool selectDegrees(Register ResVReg, const SPIRVType *ResType,
161+
MachineInstr &I) const;
162+
160163
bool selectFrac(Register ResVReg, const SPIRVType *ResType,
161164
MachineInstr &I) const;
162165

@@ -1643,6 +1646,23 @@ bool SPIRVInstructionSelector::selectLength(Register ResVReg,
16431646
.constrainAllUses(TII, TRI, RBI);
16441647
}
16451648

1649+
bool SPIRVInstructionSelector::selectDegrees(Register ResVReg,
1650+
const SPIRVType *ResType,
1651+
MachineInstr &I) const {
1652+
1653+
assert(I.getNumOperands() == 3);
1654+
assert(I.getOperand(2).isReg());
1655+
MachineBasicBlock &BB = *I.getParent();
1656+
1657+
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
1658+
.addDef(ResVReg)
1659+
.addUse(GR.getSPIRVTypeID(ResType))
1660+
.addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
1661+
.addImm(GL::Degrees)
1662+
.addUse(I.getOperand(2).getReg())
1663+
.constrainAllUses(TII, TRI, RBI);
1664+
}
1665+
16461666
bool SPIRVInstructionSelector::selectFrac(Register ResVReg,
16471667
const SPIRVType *ResType,
16481668
MachineInstr &I) const {
@@ -2625,6 +2645,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
26252645
return selectFmix(ResVReg, ResType, I);
26262646
case Intrinsic::spv_length:
26272647
return selectLength(ResVReg, ResType, I);
2648+
case Intrinsic::spv_degrees:
2649+
return selectDegrees(ResVReg, ResType, I);
26282650
case Intrinsic::spv_frac:
26292651
return selectFrac(ResVReg, ResType, I);
26302652
case Intrinsic::spv_normalize:

llvm/test/CodeGen/DirectX/degrees.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
2+
3+
; Make sure dxil op function calls for degrees are expanded and lowered as fmul for float and half.
4+
5+
define noundef half @degrees_half(half noundef %a) {
6+
; CHECK-LABEL: define noundef half @degrees_half(
7+
; CHECK-SAME: half noundef [[A:%.*]]) {
8+
; CHECK-NEXT: [[ENTRY:.*:]]
9+
; CHECK-NEXT: [[DX_DEGREES1:%.*]] = fmul half [[A]], 0xH5329
10+
; CHECK-NEXT: ret half [[DX_DEGREES1]]
11+
;
12+
entry:
13+
%dx.degrees = call half @llvm.dx.degrees.f16(half %a)
14+
ret half %dx.degrees
15+
}
16+
17+
define noundef float @degrees_float(float noundef %a) #0 {
18+
; CHECK-LABEL: define noundef float @degrees_float(
19+
; CHECK-SAME: float noundef [[A:%.*]]) {
20+
; CHECK-NEXT: [[ENTRY:.*:]]
21+
; CHECK-NEXT: [[DX_DEGREES1:%.*]] = fmul float [[A]], 0x404CA5DC20000000
22+
; CHECK-NEXT: ret float [[DX_DEGREES1]]
23+
;
24+
entry:
25+
%dx.degrees = call float @llvm.dx.degrees.f32(float %a)
26+
ret float %dx.degrees
27+
}
28+
29+
define noundef <4 x float> @degrees_float4(<4 x float> noundef %a) #0 {
30+
; CHECK-LABEL: define noundef <4 x float> @degrees_float4(
31+
; CHECK-SAME: <4 x float> noundef [[A:%.*]]) {
32+
; CHECK-NEXT: [[ENTRY:.*:]]
33+
; CHECK-NEXT: [[A_I0:%.*]] = extractelement <4 x float> [[A]], i64 0
34+
; CHECK-NEXT: [[DOTI04:%.*]] = fmul float [[A_I0]], 0x404CA5DC20000000
35+
; CHECK-NEXT: [[A_I1:%.*]] = extractelement <4 x float> [[A]], i64 1
36+
; CHECK-NEXT: [[DOTI13:%.*]] = fmul float [[A_I1]], 0x404CA5DC20000000
37+
; CHECK-NEXT: [[A_I2:%.*]] = extractelement <4 x float> [[A]], i64 2
38+
; CHECK-NEXT: [[DOTI22:%.*]] = fmul float [[A_I2]], 0x404CA5DC20000000
39+
; CHECK-NEXT: [[A_I3:%.*]] = extractelement <4 x float> [[A]], i64 3
40+
; CHECK-NEXT: [[DOTI31:%.*]] = fmul float [[A_I3]], 0x404CA5DC20000000
41+
; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <4 x float> poison, float [[DOTI04]], i64 0
42+
; CHECK-NEXT: [[DOTUPTO1:%.*]] = insertelement <4 x float> [[DOTUPTO0]], float [[DOTI13]], i64 1
43+
; CHECK-NEXT: [[DOTUPTO2:%.*]] = insertelement <4 x float> [[DOTUPTO1]], float [[DOTI22]], i64 2
44+
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x float> [[DOTUPTO2]], float [[DOTI31]], i64 3
45+
; CHECK-NEXT: ret <4 x float> [[TMP0]]
46+
;
47+
entry:
48+
%2 = call <4 x float> @llvm.dx.degrees.v4f32(<4 x float> %a)
49+
ret <4 x float> %2
50+
}
51+
52+
declare half @llvm.dx.degrees.f16(half)
53+
declare float @llvm.dx.degrees.f32(float)
54+
declare <4 x float> @llvm.dx.degrees.v4f32(<4 x float>)

0 commit comments

Comments
 (0)