Skip to content

Commit 9e3d9c9

Browse files
committed
clang: Add __builtin_elementwise_sqrt
This will be used in the opencl builtin headers to provide direct intrinsic access with proper !fpmath metadata. https://reviews.llvm.org/D156737
1 parent 43f4e2b commit 9e3d9c9

File tree

11 files changed

+102
-1
lines changed

11 files changed

+102
-1
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,8 @@ Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±in
643643
T __builtin_elementwise_bitreverse(T x) return the integer represented after reversing the bits of x integer types
644644
T __builtin_elementwise_exp(T x) returns the base-e exponential, e^x, of the specified value floating point types
645645
T __builtin_elementwise_exp2(T x) returns the base-2 exponential, 2^x, of the specified value floating point types
646+
647+
T __builtin_elementwise_sqrt(T x) return the square root of a floating-point number floating point types
646648
T __builtin_elementwise_roundeven(T x) round x to the nearest integer value in floating point format, floating point types
647649
rounding halfway cases to even (that is, to the nearest value
648650
that is an even integer), regardless of the current rounding

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ Floating Point Support in Clang
239239
- Add ``__builtin_set_flt_rounds`` builtin for X86, x86_64, Arm and AArch64 only.
240240
- Add ``__builtin_elementwise_pow`` builtin for floating point types only.
241241
- Add ``__builtin_elementwise_bitreverse`` builtin for integer types only.
242+
- Add ``__builtin_elementwise_sqrt`` builtin for floating point types only.
242243

243244
AST Matchers
244245
------------

clang/include/clang/Basic/Builtins.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ BUILTIN(__builtin_elementwise_round, "v.", "nct")
694694
BUILTIN(__builtin_elementwise_rint, "v.", "nct")
695695
BUILTIN(__builtin_elementwise_nearbyint, "v.", "nct")
696696
BUILTIN(__builtin_elementwise_sin, "v.", "nct")
697+
BUILTIN(__builtin_elementwise_sqrt, "v.", "nct")
697698
BUILTIN(__builtin_elementwise_trunc, "v.", "nct")
698699
BUILTIN(__builtin_elementwise_canonicalize, "v.", "nct")
699700
BUILTIN(__builtin_elementwise_copysign, "v.", "nct")

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2530,7 +2530,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
25302530
case Builtin::BI__builtin_sqrtf:
25312531
case Builtin::BI__builtin_sqrtf16:
25322532
case Builtin::BI__builtin_sqrtl:
2533-
case Builtin::BI__builtin_sqrtf128: {
2533+
case Builtin::BI__builtin_sqrtf128:
2534+
case Builtin::BI__builtin_elementwise_sqrt: {
25342535
llvm::Value *Call = emitUnaryMaybeConstrainedFPBuiltin(
25352536
*this, E, Intrinsic::sqrt, Intrinsic::experimental_constrained_sqrt);
25362537
SetSqrtFPAccuracy(Call);

clang/lib/Sema/SemaChecking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
26422642
case Builtin::BI__builtin_elementwise_rint:
26432643
case Builtin::BI__builtin_elementwise_nearbyint:
26442644
case Builtin::BI__builtin_elementwise_sin:
2645+
case Builtin::BI__builtin_elementwise_sqrt:
26452646
case Builtin::BI__builtin_elementwise_trunc:
26462647
case Builtin::BI__builtin_elementwise_canonicalize: {
26472648
if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))

clang/test/CodeGen/builtins-elementwise-math.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,22 @@ void test_builtin_elementwise_sin(float f1, float f2, double d1, double d2,
588588
vf2 = __builtin_elementwise_sin(vf1);
589589
}
590590

591+
void test_builtin_elementwise_sqrt(float f1, float f2, double d1, double d2,
592+
float4 vf1, float4 vf2) {
593+
// CHECK-LABEL: define void @test_builtin_elementwise_sqrt(
594+
// CHECK: [[F1:%.+]] = load float, ptr %f1.addr, align 4
595+
// CHECK-NEXT: call float @llvm.sqrt.f32(float [[F1]])
596+
f2 = __builtin_elementwise_sqrt(f1);
597+
598+
// CHECK: [[D1:%.+]] = load double, ptr %d1.addr, align 8
599+
// CHECK-NEXT: call double @llvm.sqrt.f64(double [[D1]])
600+
d2 = __builtin_elementwise_sqrt(d1);
601+
602+
// CHECK: [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16
603+
// CHECK-NEXT: call <4 x float> @llvm.sqrt.v4f32(<4 x float> [[VF1]])
604+
vf2 = __builtin_elementwise_sqrt(vf1);
605+
}
606+
591607
void test_builtin_elementwise_trunc(float f1, float f2, double d1, double d2,
592608
float4 vf1, float4 vf2) {
593609
// CHECK-LABEL: define void @test_builtin_elementwise_trunc(

clang/test/CodeGen/strictfp-elementwise-bulitins.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,16 @@ float4 strict_elementwise_sin(float4 a) {
177177
return __builtin_elementwise_sin(a);
178178
}
179179

180+
// CHECK-LABEL: define dso_local noundef <4 x float> @_Z23strict_elementwise_sqrtDv4_f
181+
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
182+
// CHECK-NEXT: entry:
183+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.experimental.constrained.sqrt.v4f32(<4 x float> [[A]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
184+
// CHECK-NEXT: ret <4 x float> [[TMP0]]
185+
//
186+
float4 strict_elementwise_sqrt(float4 a) {
187+
return __builtin_elementwise_sqrt(a);
188+
}
189+
180190
// CHECK-LABEL: define dso_local noundef <4 x float> @_Z24strict_elementwise_truncDv4_f
181191
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
182192
// CHECK-NEXT: entry:

clang/test/CodeGenCUDA/correctly-rounded-div.cu

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,18 @@ __device__ double dpscalarsqrt(double a) {
4646
return __builtin_sqrt(a);
4747
}
4848

49+
// COMMON-LABEL: @_Z28test_builtin_elementwise_f32f
50+
// NCRDIV: call contract float @llvm.sqrt.f32(float %{{.+}}), !fpmath ![[MD:[0-9]+]]
51+
// CRDIV: call contract float @llvm.sqrt.f32(float %{{.+}}){{$}}
52+
__device__ float test_builtin_elementwise_f32(float a) {
53+
return __builtin_elementwise_sqrt(a);
54+
}
55+
56+
// COMMON-LABEL: @_Z28test_builtin_elementwise_f64d
57+
// COMMON: call contract double @llvm.sqrt.f64(double %{{.+}}){{$}}
58+
// COMMON-NOT: !fpmath
59+
__device__ double test_builtin_elementwise_f64(double a) {
60+
return __builtin_elementwise_sqrt(a);
61+
}
62+
4963
// NCRSQRT: ![[MD]] = !{float 2.500000e+00}

clang/test/CodeGenOpenCL/fpmath.cl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ float spscalarsqrt(float a) {
2828
return __builtin_sqrtf(a);
2929
}
3030

31+
float elementwise_sqrt_f32(float a) {
32+
// CHECK-LABEL: @elementwise_sqrt_f32
33+
// NODIVOPT: call float @llvm.sqrt.f32(float %{{.+}}), !fpmath ![[MD_SQRT:[0-9]+]]
34+
// DIVOPT: call float @llvm.sqrt.f32(float %{{.+}}){{$}}
35+
return __builtin_elementwise_sqrt(a);
36+
}
37+
38+
float4 elementwise_sqrt_v4f32(float4 a) {
39+
// CHECK-LABEL: @elementwise_sqrt_v4f32
40+
// NODIVOPT: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %{{.+}}), !fpmath ![[MD_SQRT:[0-9]+]]
41+
// DIVOPT: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %{{.+}}){{$}}
42+
return __builtin_elementwise_sqrt(a);
43+
}
44+
45+
3146
#if __OPENCL_C_VERSION__ >=120
3247
void printf(constant char* fmt, ...);
3348

@@ -61,6 +76,18 @@ double dpscalarsqrt(double a) {
6176
return __builtin_sqrt(a);
6277
}
6378

79+
double elementwise_sqrt_f64(double a) {
80+
// CHECK-LABEL: @elementwise_sqrt_f64
81+
// CHECK: call double @llvm.sqrt.f64(double %{{.+}}){{$}}
82+
return __builtin_elementwise_sqrt(a);
83+
}
84+
85+
double4 elementwise_sqrt_v4f64(double4 a) {
86+
// CHECK-LABEL: @elementwise_sqrt_v4f64
87+
// CHECK: call <4 x double> @llvm.sqrt.v4f64(<4 x double> %{{.+}}){{$}}
88+
return __builtin_elementwise_sqrt(a);
89+
}
90+
6491
#endif
6592

6693
// NODIVOPT: ![[MD_FDIV]] = !{float 2.500000e+00}

clang/test/Sema/builtins-elementwise-math.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,27 @@ void test_builtin_elementwise_sin(int i, float f, double d, float4 v, int3 iv, u
601601
// expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
602602
}
603603

604+
void test_builtin_elementwise_sqrt(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
605+
606+
struct Foo s = __builtin_elementwise_sqrt(f);
607+
// expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}}
608+
609+
i = __builtin_elementwise_sqrt();
610+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
611+
612+
i = __builtin_elementwise_sqrt(i);
613+
// expected-error@-1 {{1st argument must be a floating point type (was 'int')}}
614+
615+
i = __builtin_elementwise_sqrt(f, f);
616+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
617+
618+
u = __builtin_elementwise_sqrt(u);
619+
// expected-error@-1 {{1st argument must be a floating point type (was 'unsigned int')}}
620+
621+
uv = __builtin_elementwise_sqrt(uv);
622+
// expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}}
623+
}
624+
604625
void test_builtin_elementwise_trunc(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
605626

606627
struct Foo s = __builtin_elementwise_trunc(f);

clang/test/SemaCXX/builtins-elementwise-math.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ void test_builtin_elementwise_sin() {
111111
static_assert(!is_const<decltype(__builtin_elementwise_sin(b))>::value);
112112
}
113113

114+
void test_builtin_elementwise_sqrt() {
115+
const float a = 42.0;
116+
float b = 42.3;
117+
static_assert(!is_const<decltype(__builtin_elementwise_sqrt(a))>::value);
118+
static_assert(!is_const<decltype(__builtin_elementwise_sqrt(b))>::value);
119+
}
120+
114121
void test_builtin_elementwise_log() {
115122
const float a = 42.0;
116123
float b = 42.3;

0 commit comments

Comments
 (0)