[clang] [HLSL] enforce unsigned types for reversebits (PR #86720)

Farzon Lotfi via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 26 12:35:37 PDT 2024


https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/86720

fixes #86719
- `SemaChecking.cpp` - Adds unsigned semaChecks to `__builtin_elementwise_bitreverse` 
- `hlsl_intrinsics.h` - remove signed `reversebits` apis

>From 0535f804c10c2c1a089a4c3c061d39b01f0ac0ee Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Tue, 26 Mar 2024 15:15:03 -0400
Subject: [PATCH] [HLSL] enforce unsigned types for reversebits fixes #86719
 `SemaChecking.cpp` - Adds unsigned semaChecks to
 `__builtin_elementwise_bitreverse` `hlsl_intrinsics.h` - remove signed
 `reversebits` apis

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h      | 31 --------
 clang/lib/Sema/SemaChecking.cpp               | 13 ++++
 .../CodeGenHLSL/builtins/reversebits.hlsl     | 75 -------------------
 .../SemaHLSL/BuiltIns/reversebits-errors.hlsl | 12 +++
 4 files changed, 25 insertions(+), 106 deletions(-)
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 18472f728eefe0..d47eab453f8747 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1147,19 +1147,6 @@ float4 pow(float4, float4);
 /// \param Val The input value.
 
 #ifdef __HLSL_ENABLE_16_BIT
-_HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int16_t reversebits(int16_t);
-_HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int16_t2 reversebits(int16_t2);
-_HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int16_t3 reversebits(int16_t3);
-_HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int16_t4 reversebits(int16_t4);
-
 _HLSL_AVAILABILITY(shadermodel, 6.2)
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint16_t reversebits(uint16_t);
@@ -1174,15 +1161,6 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint16_t4 reversebits(uint16_t4);
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int reversebits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int2 reversebits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int3 reversebits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int4 reversebits(int4);
-
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint reversebits(uint);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
@@ -1192,15 +1170,6 @@ uint3 reversebits(uint3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint4 reversebits(uint4);
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int64_t reversebits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int64_t2 reversebits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int64_t3 reversebits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
-int64_t4 reversebits(int64_t4);
-
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint64_t reversebits(uint64_t);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b4e87b61803234..d8a78cc0019ea4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5541,6 +5541,14 @@ bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) {
                                   checkDoubleVector);
 }
 
+bool CheckUnsignedIntRepresentation(Sema *S, CallExpr *TheCall) {
+  auto checkAllUnsignedTypes = [](clang::QualType PassedType) -> bool {
+    return !PassedType->hasUnsignedIntegerRepresentation();
+  };
+  return CheckArgsTypesAreCorrect(S, TheCall, S->Context.UnsignedIntTy,
+                                  checkAllUnsignedTypes);
+}
+
 void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall,
                                 QualType ReturnType) {
   auto *VecTyA = TheCall->getArg(0)->getType()->getAs<VectorType>();
@@ -5628,6 +5636,11 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   }
   // Note these are llvm builtins that we want to catch invalid intrinsic
   // generation. Normal handling of these builitns will occur elsewhere.
+  case Builtin::BI__builtin_elementwise_bitreverse: {
+    if (CheckUnsignedIntRepresentation(this, TheCall))
+      return true;
+    break;
+  }
   case Builtin::BI__builtin_elementwise_cos:
   case Builtin::BI__builtin_elementwise_sin:
   case Builtin::BI__builtin_elementwise_log:
diff --git a/clang/test/CodeGenHLSL/builtins/reversebits.hlsl b/clang/test/CodeGenHLSL/builtins/reversebits.hlsl
index 6da7d289f82e80..a319417e97a436 100644
--- a/clang/test/CodeGenHLSL/builtins/reversebits.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/reversebits.hlsl
@@ -3,31 +3,6 @@
 // RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
 
 #ifdef __HLSL_ENABLE_16_BIT
-// CHECK: define noundef i16 @
-// CHECK: call i16 @llvm.bitreverse.i16(
-int16_t test_bitreverse_short(int16_t p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <2 x i16> @
-// CHECK: call <2 x i16> @llvm.bitreverse.v2i16(
-int16_t2 test_bitreverse_short2(int16_t2 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <3 x i16> @
-// CHECK: call <3 x i16> @llvm.bitreverse.v3i16
-int16_t3 test_bitreverse_short3(int16_t3 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <4 x i16> @
-// CHECK: call <4 x i16> @llvm.bitreverse.v4i16
-int16_t4 test_bitreverse_short4(int16_t4 p0)
-{
-	return reversebits(p0);
-}
-
 // CHECK: define noundef i16 @
 // CHECK: call i16 @llvm.bitreverse.i16(
 uint16_t test_bitreverse_ushort(uint16_t p0)
@@ -54,31 +29,6 @@ uint16_t4 test_bitreverse_ushort4(uint16_t4 p0)
 }
 #endif
 
-// CHECK: define noundef i32 @
-// CHECK: call i32 @llvm.bitreverse.i32(
-int test_bitreverse_int(int p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <2 x i32> @
-// CHECK: call <2 x i32> @llvm.bitreverse.v2i32
-int2 test_bitreverse_int2(int2 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <3 x i32> @
-// CHECK: call <3 x i32> @llvm.bitreverse.v3i32
-int3 test_bitreverse_int3(int3 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <4 x i32> @
-// CHECK: call <4 x i32> @llvm.bitreverse.v4i32
-int4 test_bitreverse_int4(int4 p0)
-{
-	return reversebits(p0);
-}
-
 // CHECK: define noundef i32 @
 // CHECK: call i32 @llvm.bitreverse.i32(
 int test_bitreverse_uint(uint p0)
@@ -104,31 +54,6 @@ uint4 test_bitreverse_uint4(uint4 p0)
 	return reversebits(p0);
 }
 
-// CHECK: define noundef i64 @
-// CHECK: call i64 @llvm.bitreverse.i64(
-int64_t test_bitreverse_long(int64_t p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <2 x i64> @
-// CHECK: call <2 x i64> @llvm.bitreverse.v2i64
-int64_t2 test_bitreverse_long2(int64_t2 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <3 x i64> @
-// CHECK: call <3 x i64> @llvm.bitreverse.v3i64
-int64_t3 test_bitreverse_long3(int64_t3 p0)
-{
-	return reversebits(p0);
-}
-// CHECK: define noundef <4 x i64> @
-// CHECK: call <4 x i64> @llvm.bitreverse.v4i64
-int64_t4 test_bitreverse_long4(int64_t4 p0)
-{
-	return reversebits(p0);
-}
-
 // CHECK: define noundef i64 @
 // CHECK: call i64 @llvm.bitreverse.i64(
 uint64_t test_bitreverse_long(uint64_t p0)
diff --git a/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl
new file mode 100644
index 00000000000000..6e66db6d1cca9e
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/reversebits-errors.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify
+
+
+double2 test_int_builtin(double2 p0) {
+    return __builtin_elementwise_bitreverse(p0);
+  // expected-error at -1 {{1st argument must be a vector of integers (was 'double2' (aka 'vector<double, 2>'))}}
+}
+
+int2 test_int_builtin(int2 p0) {
+    return __builtin_elementwise_bitreverse(p0);
+  // expected-error at -1 {{passing 'int2' (aka 'vector<int, 2>') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values)}}
+}



More information about the cfe-commits mailing list