Skip to content

Commit 4036a69

Browse files
farzonlFarzon Lotfi
andauthored
[HLSL] move rcp to cgbuiltins (#88401)
Removing the intrinsic because there is no opCodes for rcp in DXIL or SPIR-V. Moving means we don't have to re-implement this feature for each backend. fixes #87784 Co-authored-by: Farzon Lotfi <[email protected]>
1 parent 9a36077 commit 4036a69

File tree

5 files changed

+224
-116
lines changed

5 files changed

+224
-116
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18303,9 +18303,16 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1830318303
Value *Op0 = EmitScalarExpr(E->getArg(0));
1830418304
if (!E->getArg(0)->getType()->hasFloatingRepresentation())
1830518305
llvm_unreachable("rcp operand must have a float representation");
18306-
return Builder.CreateIntrinsic(
18307-
/*ReturnType=*/Op0->getType(), Intrinsic::dx_rcp,
18308-
ArrayRef<Value *>{Op0}, nullptr, "dx.rcp");
18306+
llvm::Type *Ty = Op0->getType();
18307+
llvm::Type *EltTy = Ty->getScalarType();
18308+
Constant *One =
18309+
Ty->isVectorTy()
18310+
? ConstantVector::getSplat(
18311+
ElementCount::getFixed(
18312+
dyn_cast<FixedVectorType>(Ty)->getNumElements()),
18313+
ConstantFP::get(EltTy, 1.0))
18314+
: ConstantFP::get(EltTy, 1.0);
18315+
return Builder.CreateFDiv(One, Op0, "hlsl.rcp");
1830918316
}
1831018317
case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1831118318
Value *Op0 = EmitScalarExpr(E->getArg(0));
Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,102 @@
11
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
22
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
33
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
4-
// RUN: --check-prefixes=CHECK,NATIVE_HALF
4+
// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
55
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
66
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
7-
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF
8-
9-
// NATIVE_HALF: define noundef half @
10-
// NATIVE_HALF: %dx.rcp = call half @llvm.dx.rcp.f16(
11-
// NATIVE_HALF: ret half %dx.rcp
12-
// NO_HALF: define noundef float @"?test_rcp_half@@YA$halff@$halff@@Z"(
13-
// NO_HALF: %dx.rcp = call float @llvm.dx.rcp.f32(
14-
// NO_HALF: ret float %dx.rcp
7+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF
8+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
9+
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
10+
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
11+
// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK
12+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
13+
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
14+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK
15+
16+
// DXIL_NATIVE_HALF: define noundef half @
17+
// SPIR_NATIVE_HALF: define spir_func noundef half @
18+
// NATIVE_HALF: %hlsl.rcp = fdiv half 0xH3C00, %{{.*}}
19+
// NATIVE_HALF: ret half %hlsl.rcp
20+
// DXIL_NO_HALF: define noundef float @
21+
// SPIR_NO_HALF: define spir_func noundef float @
22+
// NO_HALF: %hlsl.rcp = fdiv float 1.000000e+00, %{{.*}}
23+
// NO_HALF: ret float %hlsl.rcp
1524
half test_rcp_half(half p0) { return rcp(p0); }
16-
// NATIVE_HALF: define noundef <2 x half> @
17-
// NATIVE_HALF: %dx.rcp = call <2 x half> @llvm.dx.rcp.v2f16
18-
// NATIVE_HALF: ret <2 x half> %dx.rcp
19-
// NO_HALF: define noundef <2 x float> @
20-
// NO_HALF: %dx.rcp = call <2 x float> @llvm.dx.rcp.v2f32(
21-
// NO_HALF: ret <2 x float> %dx.rcp
25+
26+
// DXIL_NATIVE_HALF: define noundef <2 x half> @
27+
// SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @
28+
// NATIVE_HALF: %hlsl.rcp = fdiv <2 x half> <half 0xH3C00, half 0xH3C00>, %{{.*}}
29+
// NATIVE_HALF: ret <2 x half> %hlsl.rcp
30+
// DXIL_NO_HALF: define noundef <2 x float> @
31+
// SPIR_NO_HALF: define spir_func noundef <2 x float> @
32+
// NO_HALF: %hlsl.rcp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %{{.*}}
33+
// NO_HALF: ret <2 x float> %hlsl.rcp
2234
half2 test_rcp_half2(half2 p0) { return rcp(p0); }
23-
// NATIVE_HALF: define noundef <3 x half> @
24-
// NATIVE_HALF: %dx.rcp = call <3 x half> @llvm.dx.rcp.v3f16
25-
// NATIVE_HALF: ret <3 x half> %dx.rcp
26-
// NO_HALF: define noundef <3 x float> @
27-
// NO_HALF: %dx.rcp = call <3 x float> @llvm.dx.rcp.v3f32(
28-
// NO_HALF: ret <3 x float> %dx.rcp
35+
36+
// DXIL_NATIVE_HALF: define noundef <3 x half> @
37+
// SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @
38+
// NATIVE_HALF: %hlsl.rcp = fdiv <3 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00>, %{{.*}}
39+
// NATIVE_HALF: ret <3 x half> %hlsl.rcp
40+
// DXIL_NO_HALF: define noundef <3 x float> @
41+
// SPIR_NO_HALF: define spir_func noundef <3 x float> @
42+
// NO_HALF: %hlsl.rcp = fdiv <3 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %{{.*}}
43+
// NO_HALF: ret <3 x float> %hlsl.rcp
2944
half3 test_rcp_half3(half3 p0) { return rcp(p0); }
30-
// NATIVE_HALF: define noundef <4 x half> @
31-
// NATIVE_HALF: %dx.rcp = call <4 x half> @llvm.dx.rcp.v4f16
32-
// NATIVE_HALF: ret <4 x half> %dx.rcp
33-
// NO_HALF: define noundef <4 x float> @
34-
// NO_HALF: %dx.rcp = call <4 x float> @llvm.dx.rcp.v4f32(
35-
// NO_HALF: ret <4 x float> %dx.rcp
45+
46+
// DXIL_NATIVE_HALF: define noundef <4 x half> @
47+
// SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @
48+
// NATIVE_HALF: %hlsl.rcp = fdiv <4 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00, half 0xH3C00>, %{{.*}}
49+
// NATIVE_HALF: ret <4 x half> %hlsl.rcp
50+
// DXIL_NO_HALF: define noundef <4 x float> @
51+
// SPIR_NO_HALF: define spir_func noundef <4 x float> @
52+
// NO_HALF: %hlsl.rcp = fdiv <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %{{.*}}
53+
// NO_HALF: ret <4 x float> %hlsl.rcp
3654
half4 test_rcp_half4(half4 p0) { return rcp(p0); }
3755

38-
// CHECK: define noundef float @
39-
// CHECK: %dx.rcp = call float @llvm.dx.rcp.f32(
40-
// CHECK: ret float %dx.rcp
56+
// DXIL_CHECK: define noundef float @
57+
// SPIR_CHECK: define spir_func noundef float @
58+
// CHECK: %hlsl.rcp = fdiv float 1.000000e+00, %{{.*}}
59+
// CHECK: ret float %hlsl.rcp
4160
float test_rcp_float(float p0) { return rcp(p0); }
42-
// CHECK: define noundef <2 x float> @
43-
// CHECK: %dx.rcp = call <2 x float> @llvm.dx.rcp.v2f32
44-
// CHECK: ret <2 x float> %dx.rcp
61+
62+
// DXIL_CHECK: define noundef <2 x float> @
63+
// SPIR_CHECK: define spir_func noundef <2 x float> @
64+
// CHECK: %hlsl.rcp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %{{.*}}
65+
// CHECK: ret <2 x float> %hlsl.rcp
4566
float2 test_rcp_float2(float2 p0) { return rcp(p0); }
46-
// CHECK: define noundef <3 x float> @
47-
// CHECK: %dx.rcp = call <3 x float> @llvm.dx.rcp.v3f32
48-
// CHECK: ret <3 x float> %dx.rcp
67+
68+
// DXIL_CHECK: define noundef <3 x float> @
69+
// SPIR_CHECK: define spir_func noundef <3 x float> @
70+
// CHECK: %hlsl.rcp = fdiv <3 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %{{.*}}
71+
// CHECK: ret <3 x float> %hlsl.rcp
4972
float3 test_rcp_float3(float3 p0) { return rcp(p0); }
50-
// CHECK: define noundef <4 x float> @
51-
// CHECK: %dx.rcp = call <4 x float> @llvm.dx.rcp.v4f32
52-
// CHECK: ret <4 x float> %dx.rcp
73+
74+
// DXIL_CHECK: define noundef <4 x float> @
75+
// SPIR_CHECK: define spir_func noundef <4 x float> @
76+
// CHECK: %hlsl.rcp = fdiv <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %{{.*}}
77+
// CHECK: ret <4 x float> %hlsl.rcp
5378
float4 test_rcp_float4(float4 p0) { return rcp(p0); }
79+
80+
// DXIL_CHECK: define noundef double @
81+
// SPIR_CHECK: define spir_func noundef double @
82+
// CHECK: %hlsl.rcp = fdiv double 1.000000e+00, %{{.*}}
83+
// CHECK: ret double %hlsl.rcp
84+
double test_rcp_double(double p0) { return rcp(p0); }
85+
86+
// DXIL_CHECK: define noundef <2 x double> @
87+
// SPIR_CHECK: define spir_func noundef <2 x double> @
88+
// CHECK: %hlsl.rcp = fdiv <2 x double> <double 1.000000e+00, double 1.000000e+00>, %{{.*}}
89+
// CHECK: ret <2 x double> %hlsl.rcp
90+
double2 test_rcp_double2(double2 p0) { return rcp(p0); }
91+
92+
// DXIL_CHECK: define noundef <3 x double> @
93+
// SPIR_CHECK: define spir_func noundef <3 x double> @
94+
// CHECK: %hlsl.rcp = fdiv <3 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, %{{.*}}
95+
// CHECK: ret <3 x double> %hlsl.rcp
96+
double3 test_rcp_double3(double3 p0) { return rcp(p0); }
97+
98+
// DXIL_CHECK: define noundef <4 x double> @
99+
// SPIR_CHECK: define spir_func noundef <4 x double> @
100+
// CHECK: %hlsl.rcp = fdiv <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, %{{.*}}
101+
// CHECK: ret <4 x double> %hlsl.rcp
102+
double4 test_rcp_double4(double4 p0) { return rcp(p0); }

llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ static bool isIntrinsicExpansion(Function &F) {
4242
case Intrinsic::dx_clamp:
4343
case Intrinsic::dx_uclamp:
4444
case Intrinsic::dx_lerp:
45-
case Intrinsic::dx_rcp:
4645
case Intrinsic::dx_sdot:
4746
case Intrinsic::dx_udot:
4847
return true;
@@ -218,25 +217,6 @@ static bool expandPowIntrinsic(CallInst *Orig) {
218217
return true;
219218
}
220219

221-
static bool expandRcpIntrinsic(CallInst *Orig) {
222-
Value *X = Orig->getOperand(0);
223-
IRBuilder<> Builder(Orig->getParent());
224-
Builder.SetInsertPoint(Orig);
225-
Type *Ty = X->getType();
226-
Type *EltTy = Ty->getScalarType();
227-
Constant *One =
228-
Ty->isVectorTy()
229-
? ConstantVector::getSplat(
230-
ElementCount::getFixed(
231-
dyn_cast<FixedVectorType>(Ty)->getNumElements()),
232-
ConstantFP::get(EltTy, 1.0))
233-
: ConstantFP::get(EltTy, 1.0);
234-
auto *Result = Builder.CreateFDiv(One, X, "dx.rcp");
235-
Orig->replaceAllUsesWith(Result);
236-
Orig->eraseFromParent();
237-
return true;
238-
}
239-
240220
static Intrinsic::ID getMaxForClamp(Type *ElemTy,
241221
Intrinsic::ID ClampIntrinsic) {
242222
if (ClampIntrinsic == Intrinsic::dx_uclamp)
@@ -300,8 +280,6 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
300280
return expandClampIntrinsic(Orig, F.getIntrinsicID());
301281
case Intrinsic::dx_lerp:
302282
return expandLerpIntrinsic(Orig);
303-
case Intrinsic::dx_rcp:
304-
return expandRcpIntrinsic(Orig);
305283
case Intrinsic::dx_sdot:
306284
case Intrinsic::dx_udot:
307285
return expandIntegerDot(Orig, F.getIntrinsicID());

llvm/test/CodeGen/DirectX/rcp.ll

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
3+
; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
4+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
5+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
6+
; CHECK-DAG: %[[#vec2_float_16:]] = OpTypeVector %[[#float_16]] 2
7+
; CHECK-DAG: %[[#vec2_float_32:]] = OpTypeVector %[[#float_32]] 2
8+
; CHECK-DAG: %[[#vec2_float_64:]] = OpTypeVector %[[#float_64]] 2
9+
; CHECK-DAG: %[[#vec3_float_16:]] = OpTypeVector %[[#float_16]] 3
10+
; CHECK-DAG: %[[#vec3_float_32:]] = OpTypeVector %[[#float_32]] 3
11+
; CHECK-DAG: %[[#vec3_float_64:]] = OpTypeVector %[[#float_64]] 3
12+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
13+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
14+
; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
15+
; CHECK-DAG: %[[#const_f64_1:]] = OpConstant %[[#float_64]] 1
16+
; CHECK-DAG: %[[#const_f32_1:]] = OpConstant %[[#float_32:]] 1
17+
; CHECK-DAG: %[[#const_f16_1:]] = OpConstant %[[#float_16:]] 1
18+
19+
; CHECK-DAG: %[[#vec2_const_ones_f16:]] = OpConstantComposite %[[#vec2_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]]
20+
; CHECK-DAG: %[[#vec3_const_ones_f16:]] = OpConstantComposite %[[#vec3_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]]
21+
; CHECK-DAG: %[[#vec4_const_ones_f16:]] = OpConstantComposite %[[#vec4_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]]
22+
23+
; CHECK-DAG: %[[#vec2_const_ones_f32:]] = OpConstantComposite %[[#vec2_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]]
24+
; CHECK-DAG: %[[#vec3_const_ones_f32:]] = OpConstantComposite %[[#vec3_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]]
25+
; CHECK-DAG: %[[#vec4_const_ones_f32:]] = OpConstantComposite %[[#vec4_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]]
26+
27+
; CHECK-DAG: %[[#vec2_const_ones_f64:]] = OpConstantComposite %[[#vec2_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]]
28+
; CHECK-DAG: %[[#vec3_const_ones_f64:]] = OpConstantComposite %[[#vec3_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]]
29+
; CHECK-DAG: %[[#vec4_const_ones_f64:]] = OpConstantComposite %[[#vec4_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]]
30+
31+
32+
define spir_func noundef half @test_rcp_half(half noundef %p0) #0 {
33+
entry:
34+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_16:]]
35+
; CHECK: OpFDiv %[[#float_16:]] %[[#const_f16_1:]] %[[#arg0:]]
36+
%hlsl.rcp = fdiv half 0xH3C00, %p0
37+
ret half %hlsl.rcp
38+
}
39+
40+
define spir_func noundef <2 x half> @test_rcp_half2(<2 x half> noundef %p0) #0 {
41+
entry:
42+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_16:]]
43+
; CHECK: OpFDiv %[[#vec2_float_16:]] %[[#vec2_const_ones_f16:]] %[[#arg0:]]
44+
%hlsl.rcp = fdiv <2 x half> <half 0xH3C00, half 0xH3C00>, %p0
45+
ret <2 x half> %hlsl.rcp
46+
}
47+
48+
define spir_func noundef <3 x half> @test_rcp_half3(<3 x half> noundef %p0) #0 {
49+
entry:
50+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_16:]]
51+
; CHECK: OpFDiv %[[#vec3_float_16:]] %[[#vec3_const_ones_f16:]] %[[#arg0:]]
52+
%hlsl.rcp = fdiv <3 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00>, %p0
53+
ret <3 x half> %hlsl.rcp
54+
}
55+
56+
define spir_func noundef <4 x half> @test_rcp_half4(<4 x half> noundef %p0) #0 {
57+
entry:
58+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16:]]
59+
; CHECK: OpFDiv %[[#vec4_float_16:]] %[[#vec4_const_ones_f16:]] %[[#arg0:]]
60+
%hlsl.rcp = fdiv <4 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00, half 0xH3C00>, %p0
61+
ret <4 x half> %hlsl.rcp
62+
}
63+
64+
define spir_func noundef float @test_rcp_float(float noundef %p0) #0 {
65+
entry:
66+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_32:]]
67+
; CHECK: OpFDiv %[[#float_32:]] %[[#const_f32_1:]] %[[#arg0:]]
68+
%hlsl.rcp = fdiv float 1.000000e+00, %p0
69+
ret float %hlsl.rcp
70+
}
71+
72+
define spir_func noundef <2 x float> @test_rcp_float2(<2 x float> noundef %p0) #0 {
73+
entry:
74+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_32:]]
75+
; CHECK: OpFDiv %[[#vec2_float_32:]] %[[#vec2_const_ones_f32:]] %[[#arg0:]]
76+
%hlsl.rcp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %p0
77+
ret <2 x float> %hlsl.rcp
78+
}
79+
80+
define spir_func noundef <3 x float> @test_rcp_float3(<3 x float> noundef %p0) #0 {
81+
entry:
82+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_32:]]
83+
; CHECK: OpFDiv %[[#vec3_float_32:]] %[[#vec3_const_ones_f32:]] %[[#arg0:]]
84+
%hlsl.rcp = fdiv <3 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %p0
85+
ret <3 x float> %hlsl.rcp
86+
}
87+
88+
define spir_func noundef <4 x float> @test_rcp_float4(<4 x float> noundef %p0) #0 {
89+
entry:
90+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32:]]
91+
; CHECK: OpFDiv %[[#vec4_float_32:]] %[[#vec4_const_ones_f32:]] %[[#arg0:]]
92+
%hlsl.rcp = fdiv <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %p0
93+
ret <4 x float> %hlsl.rcp
94+
}
95+
96+
define spir_func noundef double @test_rcp_double(double noundef %p0) #0 {
97+
entry:
98+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_64:]]
99+
; CHECK: OpFDiv %[[#float_64:]] %[[#const_f64_1:]] %[[#arg0:]]
100+
%hlsl.rcp = fdiv double 1.000000e+00, %p0
101+
ret double %hlsl.rcp
102+
}
103+
104+
define spir_func noundef <2 x double> @test_rcp_double2(<2 x double> noundef %p0) #0 {
105+
entry:
106+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_64:]]
107+
; CHECK: OpFDiv %[[#vec2_float_64:]] %[[#vec2_const_ones_f64:]] %[[#arg0:]]
108+
%hlsl.rcp = fdiv <2 x double> <double 1.000000e+00, double 1.000000e+00>, %p0
109+
ret <2 x double> %hlsl.rcp
110+
}
111+
112+
define spir_func noundef <3 x double> @test_rcp_double3(<3 x double> noundef %p0) #0 {
113+
entry:
114+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_64:]]
115+
; CHECK: OpFDiv %[[#vec3_float_64:]] %[[#vec3_const_ones_f64:]] %[[#arg0:]]
116+
%hlsl.rcp = fdiv <3 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, %p0
117+
ret <3 x double> %hlsl.rcp
118+
}
119+
120+
define spir_func noundef <4 x double> @test_rcp_double4(<4 x double> noundef %p0) #0 {
121+
entry:
122+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_64:]]
123+
; CHECK: OpFDiv %[[#vec4_float_64:]] %[[#vec4_const_ones_f64:]] %[[#arg0:]]
124+
%hlsl.rcp = fdiv <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, %p0
125+
ret <4 x double> %hlsl.rcp
126+
}

0 commit comments

Comments
 (0)