Skip to content

Commit 57f879c

Browse files
committed
clang: Add elementwise bitreverse builtin
Add codegen for llvm bitreverse elementwise builtin The bitreverse elementwise builtin is necessary for HLSL codegen. Tests were added to make sure that the expected errors are encountered when these functions are given inputs of incompatible types, or too many inputs. The new builtin is restricted to integer types only. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D156357
1 parent b402487 commit 57f879c

File tree

8 files changed

+98
-1
lines changed

8 files changed

+98
-1
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±in
631631
=========================================== ================================================================ =========================================
632632
T __builtin_elementwise_abs(T x) return the absolute value of a number x; the absolute value of signed integer and floating point types
633633
the most negative integer remains the most negative integer
634-
T __builtin_elementwise_fma(T x, T y, T z) fused multiply add, (x * y) + z. floating point types
634+
T __builtin_elementwise_fma(T x, T y, T z) fused multiply add, (x * y) + z. floating point types
635635
T __builtin_elementwise_ceil(T x) return the smallest integral value greater than or equal to x floating point types
636636
T __builtin_elementwise_sin(T x) return the sine of x interpreted as an angle in radians floating point types
637637
T __builtin_elementwise_cos(T x) return the cosine of x interpreted as an angle in radians floating point types
@@ -640,6 +640,7 @@ Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±in
640640
T __builtin_elementwise_log2(T x) return the base 2 logarithm of x floating point types
641641
T __builtin_elementwise_log10(T x) return the base 10 logarithm of x floating point types
642642
T __builtin_elementwise_pow(T x, T y) return x raised to the power of y floating point types
643+
T __builtin_elementwise_bitreverse(T x) return the integer represented after reversing the bits of x integer types
643644
T __builtin_elementwise_exp(T x) returns the base-e exponential, e^x, of the specified value floating point types
644645
T __builtin_elementwise_exp2(T x) returns the base-2 exponential, 2^x, of the specified value floating point types
645646
T __builtin_elementwise_roundeven(T x) round x to the nearest integer value in floating point format, floating point types

clang/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ DWARF Support in Clang
182182

183183
Floating Point Support in Clang
184184
-------------------------------
185+
- Add ``__builtin_elementwise_log`` builtin for floating point types only.
186+
- Add ``__builtin_elementwise_log10`` builtin for floating point types only.
187+
- Add ``__builtin_elementwise_log2`` builtin for floating point types only.
188+
- Add ``__builtin_elementwise_exp`` builtin for floating point types only.
189+
- Add ``__builtin_elementwise_exp2`` builtin for floating point types only.
190+
- Add ``__builtin_set_flt_rounds`` builtin for X86, x86_64, Arm and AArch64 only.
191+
- Add ``__builtin_elementwise_pow`` builtin for floating point types only.
192+
- Add ``__builtin_elementwise_bitreverse`` builtin for integer types only.
185193

186194
AST Matchers
187195
------------

clang/include/clang/Basic/Builtins.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
677677
BUILTIN(__builtin_nondeterministic_value, "v.", "nt")
678678

679679
BUILTIN(__builtin_elementwise_abs, "v.", "nct")
680+
BUILTIN(__builtin_elementwise_bitreverse, "v.", "nct")
680681
BUILTIN(__builtin_elementwise_max, "v.", "nct")
681682
BUILTIN(__builtin_elementwise_min, "v.", "nct")
682683
BUILTIN(__builtin_elementwise_ceil, "v.", "nct")

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,6 +3237,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
32373237
case Builtin::BI__builtin_elementwise_pow: {
32383238
return RValue::get(emitBinaryBuiltin(*this, E, llvm::Intrinsic::pow));
32393239
}
3240+
case Builtin::BI__builtin_elementwise_bitreverse:
3241+
return RValue::get(emitUnaryBuiltin(*this, E, llvm::Intrinsic::bitreverse,
3242+
"elt.bitreverse"));
32403243
case Builtin::BI__builtin_elementwise_cos:
32413244
return RValue::get(
32423245
emitUnaryBuiltin(*this, E, llvm::Intrinsic::cos, "elt.cos"));

clang/lib/Sema/SemaChecking.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,26 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
27002700
if (SemaBuiltinElementwiseMath(TheCall))
27012701
return ExprError();
27022702
break;
2703+
2704+
case Builtin::BI__builtin_elementwise_bitreverse: {
2705+
if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2706+
return ExprError();
2707+
2708+
const Expr *Arg = TheCall->getArg(0);
2709+
QualType ArgTy = Arg->getType();
2710+
QualType EltTy = ArgTy;
2711+
2712+
if (auto *VecTy = EltTy->getAs<VectorType>())
2713+
EltTy = VecTy->getElementType();
2714+
2715+
if (!EltTy->isIntegerType()) {
2716+
Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2717+
<< 1 << /* integer ty */ 6 << ArgTy;
2718+
return ExprError();
2719+
}
2720+
break;
2721+
}
2722+
27032723
case Builtin::BI__builtin_elementwise_copysign: {
27042724
if (checkArgCount(*this, TheCall, 2))
27052725
return ExprError();

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,42 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2,
323323
int_as_one = __builtin_elementwise_min(int_as_one, b);
324324
}
325325

326+
void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2,
327+
long long int i1, long long int i2, short si,
328+
_BitInt(31) bi1, _BitInt(31) bi2) {
329+
330+
331+
// CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8
332+
// CHECK-NEXT: call i64 @llvm.bitreverse.i64(i64 [[I1]])
333+
i2 = __builtin_elementwise_bitreverse(i1);
334+
335+
// CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16
336+
// CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[VI1]])
337+
vi2 = __builtin_elementwise_bitreverse(vi1);
338+
339+
// CHECK: [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16
340+
// CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[CVI2]])
341+
const si8 cvi2 = vi2;
342+
vi2 = __builtin_elementwise_bitreverse(cvi2);
343+
344+
// CHECK: [[BI1:%.+]] = load i31, ptr %bi1.addr, align 4
345+
// CHECK-NEXT: call i31 @llvm.bitreverse.i31(i31 [[BI1]])
346+
bi2 = __builtin_elementwise_bitreverse(bi1);
347+
348+
// CHECK: [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4
349+
// CHECK-NEXT: call i32 @llvm.bitreverse.i32(i32 [[IA1]])
350+
b = __builtin_elementwise_bitreverse(int_as_one);
351+
352+
// CHECK: call i32 @llvm.bitreverse.i32(i32 -10)
353+
b = __builtin_elementwise_bitreverse(-10);
354+
355+
// CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2
356+
// CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
357+
// CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.bitreverse.i32(i32 [[SI_EXT]])
358+
// CHECK-NEXT: = trunc i32 [[RES]] to i16
359+
si = __builtin_elementwise_bitreverse(si);
360+
}
361+
326362
void test_builtin_elementwise_ceil(float f1, float f2, double d1, double d2,
327363
float4 vf1, float4 vf2) {
328364
// CHECK-LABEL: define void @test_builtin_elementwise_ceil(

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,27 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u
269269
// expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}}
270270
}
271271

272+
void test_builtin_elementwise_bitreverse(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
273+
274+
struct Foo s = __builtin_elementwise_ceil(f);
275+
// expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}}
276+
277+
i = __builtin_elementwise_bitreverse();
278+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
279+
280+
i = __builtin_elementwise_bitreverse(f);
281+
// expected-error@-1 {{1st argument must be a vector of integers (was 'float')}}
282+
283+
i = __builtin_elementwise_bitreverse(f, f);
284+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
285+
286+
u = __builtin_elementwise_bitreverse(d);
287+
// expected-error@-1 {{1st argument must be a vector of integers (was 'double')}}
288+
289+
v = __builtin_elementwise_bitreverse(v);
290+
// expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}}
291+
}
292+
272293
void test_builtin_elementwise_ceil(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) {
273294

274295
struct Foo s = __builtin_elementwise_ceil(f);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,10 @@ void test_builtin_elementwise_pow() {
206206
static_assert(!is_const<decltype(__builtin_elementwise_pow(b, a))>::value);
207207
static_assert(!is_const<decltype(__builtin_elementwise_pow(a, a))>::value);
208208
}
209+
210+
void test_builtin_elementwise_bitreverse() {
211+
const int a = 2;
212+
int b = 1;
213+
static_assert(!is_const<decltype(__builtin_elementwise_bitreverse(a))>::value);
214+
static_assert(!is_const<decltype(__builtin_elementwise_bitreverse(b))>::value);
215+
}

0 commit comments

Comments
 (0)