Skip to content

Commit 4cea2d0

Browse files
authored
[HLSL][DXIL] implement sqrt intrinsic (#86560)
completes #86187 - fix hlsl_intrinsic to cover the correct cases - move to using `__builtin_elementwise_sqrt` - add lowering of `Intrinsic::sqrt` to dxilop 24.
1 parent 060df78 commit 4cea2d0

File tree

5 files changed

+105
-35
lines changed

5 files changed

+105
-35
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,14 +1366,26 @@ float4 sin(float4);
13661366
/// \param Val The input value.
13671367

13681368
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1369-
_HLSL_BUILTIN_ALIAS(__builtin_sqrtf16)
1370-
half sqrt(half In);
1371-
1372-
_HLSL_BUILTIN_ALIAS(__builtin_sqrtf)
1373-
float sqrt(float In);
1374-
1375-
_HLSL_BUILTIN_ALIAS(__builtin_sqrt)
1376-
double sqrt(double In);
1369+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1370+
half sqrt(half);
1371+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1372+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1373+
half2 sqrt(half2);
1374+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1375+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1376+
half3 sqrt(half3);
1377+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1378+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1379+
half4 sqrt(half4);
1380+
1381+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1382+
float sqrt(float);
1383+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1384+
float2 sqrt(float2);
1385+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1386+
float3 sqrt(float3);
1387+
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
1388+
float4 sqrt(float4);
13771389

13781390
//===----------------------------------------------------------------------===//
13791391
// trunc builtins
Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,53 @@
1-
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
2-
// RUN: dxil-pc-shadermodel6.2-library %s -fnative-half-type \
3-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s
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: %clang_cc1 -finclude-default-header -x hlsl -triple \
6+
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
7+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF
48

5-
using hlsl::sqrt;
9+
// NATIVE_HALF: define noundef half @
10+
// NATIVE_HALF: %{{.*}} = call half @llvm.sqrt.f16(
11+
// NATIVE_HALF: ret half %{{.*}}
12+
// NO_HALF: define noundef float @"?test_sqrt_half@@YA$halff@$halff@@Z"(
13+
// NO_HALF: %{{.*}} = call float @llvm.sqrt.f32(
14+
// NO_HALF: ret float %{{.*}}
15+
half test_sqrt_half(half p0) { return sqrt(p0); }
16+
// NATIVE_HALF: define noundef <2 x half> @
17+
// NATIVE_HALF: %{{.*}} = call <2 x half> @llvm.sqrt.v2f16
18+
// NATIVE_HALF: ret <2 x half> %{{.*}}
19+
// NO_HALF: define noundef <2 x float> @
20+
// NO_HALF: %{{.*}} = call <2 x float> @llvm.sqrt.v2f32(
21+
// NO_HALF: ret <2 x float> %{{.*}}
22+
half2 test_sqrt_half2(half2 p0) { return sqrt(p0); }
23+
// NATIVE_HALF: define noundef <3 x half> @
24+
// NATIVE_HALF: %{{.*}} = call <3 x half> @llvm.sqrt.v3f16
25+
// NATIVE_HALF: ret <3 x half> %{{.*}}
26+
// NO_HALF: define noundef <3 x float> @
27+
// NO_HALF: %{{.*}} = call <3 x float> @llvm.sqrt.v3f32(
28+
// NO_HALF: ret <3 x float> %{{.*}}
29+
half3 test_sqrt_half3(half3 p0) { return sqrt(p0); }
30+
// NATIVE_HALF: define noundef <4 x half> @
31+
// NATIVE_HALF: %{{.*}} = call <4 x half> @llvm.sqrt.v4f16
32+
// NATIVE_HALF: ret <4 x half> %{{.*}}
33+
// NO_HALF: define noundef <4 x float> @
34+
// NO_HALF: %{{.*}} = call <4 x float> @llvm.sqrt.v4f32(
35+
// NO_HALF: ret <4 x float> %{{.*}}
36+
half4 test_sqrt_half4(half4 p0) { return sqrt(p0); }
637

7-
double sqrt_d(double x)
8-
{
9-
return sqrt(x);
10-
}
11-
12-
// CHECK: define noundef double @"?sqrt_d@@YANN@Z"(
13-
// CHECK: call double @llvm.sqrt.f64(double %0)
14-
15-
float sqrt_f(float x)
16-
{
17-
return sqrt(x);
18-
}
19-
20-
// CHECK: define noundef float @"?sqrt_f@@YAMM@Z"(
21-
// CHECK: call float @llvm.sqrt.f32(float %0)
22-
23-
half sqrt_h(half x)
24-
{
25-
return sqrt(x);
26-
}
27-
28-
// CHECK: define noundef half @"?sqrt_h@@YA$f16@$f16@@Z"(
29-
// CHECK: call half @llvm.sqrt.f16(half %0)
38+
// CHECK: define noundef float @
39+
// CHECK: %{{.*}} = call float @llvm.sqrt.f32(
40+
// CHECK: ret float %{{.*}}
41+
float test_sqrt_float(float p0) { return sqrt(p0); }
42+
// CHECK: define noundef <2 x float> @
43+
// CHECK: %{{.*}} = call <2 x float> @llvm.sqrt.v2f32
44+
// CHECK: ret <2 x float> %{{.*}}
45+
float2 test_sqrt_float2(float2 p0) { return sqrt(p0); }
46+
// CHECK: define noundef <3 x float> @
47+
// CHECK: %{{.*}} = call <3 x float> @llvm.sqrt.v3f32
48+
// CHECK: ret <3 x float> %{{.*}}
49+
float3 test_sqrt_float3(float3 p0) { return sqrt(p0); }
50+
// CHECK: define noundef <4 x float> @
51+
// CHECK: %{{.*}} = call <4 x float> @llvm.sqrt.v4f32
52+
// CHECK: ret <4 x float> %{{.*}}
53+
float4 test_sqrt_float4(float4 p0) { return sqrt(p0); }

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ def Frac : DXILOpMapping<22, unary, int_dx_frac,
274274
"Returns a fraction from 0 to 1 that represents the "
275275
"decimal part of the input.",
276276
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
277+
def Sqrt : DXILOpMapping<24, unary, int_sqrt,
278+
"Returns the square root of the specified floating-point"
279+
"value, per component.",
280+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
277281
def RSqrt : DXILOpMapping<25, unary, int_dx_rsqrt,
278282
"Returns the reciprocal of the square root of the specified value."
279283
"rsqrt(x) = 1 / sqrt(x).",

llvm/test/CodeGen/DirectX/sqrt.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for sqrt are generated for float and half.
4+
5+
define noundef float @sqrt_float(float noundef %a) #0 {
6+
entry:
7+
; CHECK:call float @dx.op.unary.f32(i32 24, float %{{.*}})
8+
%elt.sqrt = call float @llvm.sqrt.f32(float %a)
9+
ret float %elt.sqrt
10+
}
11+
12+
define noundef half @sqrt_half(half noundef %a) #0 {
13+
entry:
14+
; CHECK:call half @dx.op.unary.f16(i32 24, half %{{.*}})
15+
%elt.sqrt = call half @llvm.sqrt.f16(half %a)
16+
ret half %elt.sqrt
17+
}
18+
19+
declare half @llvm.sqrt.f16(half)
20+
declare float @llvm.sqrt.f32(float)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
2+
3+
; DXIL operation sqrt does not support double overload type
4+
; CHECK: LLVM ERROR: Invalid Overload Type
5+
6+
define noundef double @sqrt_double(double noundef %a) {
7+
entry:
8+
%elt.sqrt = call double @llvm.sqrt.f64(double %a)
9+
ret double %elt.sqrt
10+
}

0 commit comments

Comments
 (0)