[HLSL][DXIL][SPIRV] QuadReadAcrossDiagonal intrinsic support#188567
Conversation
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-backend-directx Author: Kai (kcloudy0717) ChangesThis PR adds QuadReadAcrossDiagonal intrinsic support in HLSL with codegen for both DirectX and SPIRV backends. Resolves #99177.
Patch is 32.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/188567.diff 16 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index b8621a0dff1f0..bde0820570ec9 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5288,6 +5288,12 @@ def HLSLQuadReadAcrossY : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLQuadReadAcrossDiagonal : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_quad_read_across_diagonal"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
+
def HLSLClamp : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_clamp"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 29c41893bdbc4..3e15ed05ad645 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -1455,6 +1455,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
&CGM.getModule(), ID, {OpExpr->getType()}),
ArrayRef{OpExpr}, "hlsl.quad.read.across.y");
}
+ case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
+ Value *OpExpr = EmitScalarExpr(E->getArg(0));
+ Intrinsic::ID ID =
+ CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
+ return EmitRuntimeCall(Intrinsic::getOrInsertDeclaration(
+ &CGM.getModule(), ID, {OpExpr->getType()}),
+ ArrayRef{OpExpr}, "hlsl.quad.read.across.diagonal");
+ }
case Builtin::BI__builtin_hlsl_elementwise_sign: {
auto *Arg0 = E->getArg(0);
Value *Op0 = EmitScalarExpr(Arg0);
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index c3f3bde241b65..0c159fd1f61fc 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -160,6 +160,8 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossX, quad_read_across_x)
GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossY, quad_read_across_y)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossDiagonal,
+ quad_read_across_diagonal)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitLow, firstbitlow)
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 62cbdb0e3ba07..9d723e49b7555 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -3740,6 +3740,105 @@ __attribute__((convergent)) double3 QuadReadAcrossY(double3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_y)
__attribute__((convergent)) double4 QuadReadAcrossY(double4);
+//===----------------------------------------------------------------------===//
+// QuadReadAcrossDiagonal builtins
+//===----------------------------------------------------------------------===//
+
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half QuadReadAcrossDiagonal(half);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half2 QuadReadAcrossDiagonal(half2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half3 QuadReadAcrossDiagonal(half3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half4 QuadReadAcrossDiagonal(half4);
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t QuadReadAcrossDiagonal(int16_t);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t2 QuadReadAcrossDiagonal(int16_t2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t3 QuadReadAcrossDiagonal(int16_t3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t4 QuadReadAcrossDiagonal(int16_t4);
+
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t QuadReadAcrossDiagonal(uint16_t);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t2 QuadReadAcrossDiagonal(uint16_t2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t3 QuadReadAcrossDiagonal(uint16_t3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t4 QuadReadAcrossDiagonal(uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int QuadReadAcrossDiagonal(int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int2 QuadReadAcrossDiagonal(int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int3 QuadReadAcrossDiagonal(int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int4 QuadReadAcrossDiagonal(int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint QuadReadAcrossDiagonal(uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint2 QuadReadAcrossDiagonal(uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint3 QuadReadAcrossDiagonal(uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint4 QuadReadAcrossDiagonal(uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t QuadReadAcrossDiagonal(int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t2 QuadReadAcrossDiagonal(int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t3 QuadReadAcrossDiagonal(int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t4 QuadReadAcrossDiagonal(int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t QuadReadAcrossDiagonal(uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t2 QuadReadAcrossDiagonal(uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t3 QuadReadAcrossDiagonal(uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t4 QuadReadAcrossDiagonal(uint64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float QuadReadAcrossDiagonal(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float2 QuadReadAcrossDiagonal(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float3 QuadReadAcrossDiagonal(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float4 QuadReadAcrossDiagonal(float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double QuadReadAcrossDiagonal(double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double2 QuadReadAcrossDiagonal(double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double3 QuadReadAcrossDiagonal(double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double4 QuadReadAcrossDiagonal(double4);
+
//===----------------------------------------------------------------------===//
// sign builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aebe284b2399a..490b56b743cdb 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4308,7 +4308,8 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
case Builtin::BI__builtin_hlsl_quad_read_across_x:
- case Builtin::BI__builtin_hlsl_quad_read_across_y: {
+ case Builtin::BI__builtin_hlsl_quad_read_across_y:
+ case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
if (SemaRef.checkArgCount(TheCall, 1))
return true;
diff --git a/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl b/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl
new file mode 100644
index 0000000000000..f89be574e8e75
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl
@@ -0,0 +1,171 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -fnative-half-type -fnative-int16-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,CHECK-DXIL,CHECK-NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL,CHECK-NO_HALF
+
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,CHECK-SPIRV,CHECK-NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV,CHECK-NO_HALF
+
+// Capture the expected interchange format so not every check needs to be duplicated
+// CHECK-DXIL: %[[RET:.*]] = call [[CC:]]i32 @llvm.[[ICF:dx]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK-SPIRV: %[[RET:.*]] = call [[CC:spir_func ]]i32 @llvm.[[ICF:spv]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK: ret i32 %[[RET]]
+int test_int(int expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v2i32(<2 x i32> %[[#]])
+// CHECK: ret <2 x i32> %[[RET]]
+int2 test_int2(int2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v3i32(<3 x i32> %[[#]])
+// CHECK: ret <3 x i32> %[[RET]]
+int3 test_int3(int3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v4i32(<4 x i32> %[[#]])
+// CHECK: ret <4 x i32> %[[RET]]
+int4 test_int4(int4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i32 @llvm.[[ICF]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK: ret i32 %[[RET]]
+uint test_uint(uint expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v2i32(<2 x i32> %[[#]])
+// CHECK: ret <2 x i32> %[[RET]]
+uint2 test_uint2(uint2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v3i32(<3 x i32> %[[#]])
+// CHECK: ret <3 x i32> %[[RET]]
+uint3 test_uint3(uint3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v4i32(<4 x i32> %[[#]])
+// CHECK: ret <4 x i32> %[[RET]]
+uint4 test_uint4(uint4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i64 @llvm.[[ICF]].quad.read.across.diagonal.i64(i64 %[[#]])
+// CHECK: ret i64 %[[RET]]
+int64_t test_int64_t(int64_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v2i64(<2 x i64> %[[#]])
+// CHECK: ret <2 x i64> %[[RET]]
+int64_t2 test_int64_t2(int64_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v3i64(<3 x i64> %[[#]])
+// CHECK: ret <3 x i64> %[[RET]]
+int64_t3 test_int64_t3(int64_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v4i64(<4 x i64> %[[#]])
+// CHECK: ret <4 x i64> %[[RET]]
+int64_t4 test_int64_t4(int64_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i64 @llvm.[[ICF]].quad.read.across.diagonal.i64(i64 %[[#]])
+// CHECK: ret i64 %[[RET]]
+uint64_t test_uint64_t(uint64_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v2i64(<2 x i64> %[[#]])
+// CHECK: ret <2 x i64> %[[RET]]
+uint64_t2 test_uint64_t2(uint64_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v3i64(<3 x i64> %[[#]])
+// CHECK: ret <3 x i64> %[[RET]]
+uint64_t3 test_uint64_t3(uint64_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v4i64(<4 x i64> %[[#]])
+// CHECK: ret <4 x i64> %[[RET]]
+uint64_t4 test_uint64_t4(uint64_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]float @llvm.[[ICF]].quad.read.across.diagonal.f32(float %[[#]])
+// CHECK: ret float %[[RET]]
+float test_float(float expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x float> @llvm.[[ICF]].quad.read.across.diagonal.v2f32(<2 x float> %[[#]])
+// CHECK: ret <2 x float> %[[RET]]
+float2 test_float2(float2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x float> @llvm.[[ICF]].quad.read.across.diagonal.v3f32(<3 x float> %[[#]])
+// CHECK: ret <3 x float> %[[RET]]
+float3 test_float3(float3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x float> @llvm.[[ICF]].quad.read.across.diagonal.v4f32(<4 x float> %[[#]])
+// CHECK: ret <4 x float> %[[RET]]
+float4 test_float4(float4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]double @llvm.[[ICF]].quad.read.across.diagonal.f64(double %[[#]])
+// CHECK: ret double %[[RET]]
+double test_double(double expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x double> @llvm.[[ICF]].quad.read.across.diagonal.v2f64(<2 x double> %[[#]])
+// CHECK: ret <2 x double> %[[RET]]
+double2 test_double2(double2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x double> @llvm.[[ICF]].quad.read.across.diagonal.v3f64(<3 x double> %[[#]])
+// CHECK: ret <3 x double> %[[RET]]
+double3 test_double3(double3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x double> @llvm.[[ICF]].quad.read.across.diagonal.v4f64(<4 x double> %[[#]])
+// CHECK: ret <4 x double> %[[RET]]
+double4 test_double4(double4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]half @llvm.[[ICF]].quad.read.across.diagonal.f16(half %[[#]])
+// CHECK-NATIVE_HALF: ret half %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]float @llvm.[[ICF]].quad.read.across.diagonal.f32(float %[[#]])
+// CHECK-NO_HALF: ret float %[[RET]]
+half test_half(half expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x half> @llvm.[[ICF]].quad.read.across.diagonal.v2f16(<2 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x float> @llvm.[[ICF]].quad.read.across.diagonal.v2f32(<2 x float> %[[#]])
+// CHECK-NO_HALF: ret <2 x float> %[[RET]]
+half2 test_half2(half2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x half> @llvm.[[ICF]].quad.read.across.diagonal.v3f16(<3 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x float> @llvm.[[ICF]].quad.read.across.diagonal.v3f32(<3 x float> %[[#]])
+// CHECK-NO_HALF: ret <3 x float> %[[RET]]
+half3 test_half3(half3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x half> @llvm.[[ICF]].quad.read.across.diagonal.v4f16(<4 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x float> @llvm.[[ICF]].quad.read.across.diagonal.v4f32(<4 x float> %[[#]])
+// CHECK-NO_HALF: ret <4 x float> %[[RET]]
+half4 test_half4(half4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+#ifdef __HLSL_ENABLE_16_BIT
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]i16 @llvm.[[ICF]].quad.read.across.diagonal.i16(i16 %[[#]])
+// CHECK-NATIVE_HALF: ret i16 %[[RET]]
+int16_t test_int16_t(int16_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<2 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v2i16(<2 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x i16> %[[RET]]
+int16_t2 test_int16_t2(int16_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<3 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v3i16(<3 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x i16> %[[RET]]
+int16_t3 test_int16_t3(int16_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<4 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v4i16(<4 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x i16> %[[RET]]
+int16_t4 test_int16_t4(int16_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]i16 @llvm.[[ICF]].quad.read.across.diagonal.i16(i16 %[[#]])
+// CHECK-NATIVE_HALF: ret i16 %[[RET]]
+uint16_t test_uint16_t(uint16_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<2 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v2i16(<2 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x i16> %[[RET]]
+uint16_t2 test_uint16_t2(uint16_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<3 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v3i16(<3 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x i16> %[[RET]]
+uint16_t3 test_uint16_t3(uint16_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<4 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v4i16(<4 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x i16> %[[RET]]
+uint16_t4 test_uint16_t4(uint16_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+#endif
diff --git a/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl
new file mode 100644
index 0000000000000..322eacd7ca798
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -finclude-defau...
[truncated]
|
|
@llvm/pr-subscribers-backend-spir-v Author: Kai (kcloudy0717) ChangesThis PR adds QuadReadAcrossDiagonal intrinsic support in HLSL with codegen for both DirectX and SPIRV backends. Resolves #99177.
Patch is 32.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/188567.diff 16 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index b8621a0dff1f0..bde0820570ec9 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5288,6 +5288,12 @@ def HLSLQuadReadAcrossY : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLQuadReadAcrossDiagonal : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_quad_read_across_diagonal"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
+
def HLSLClamp : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_clamp"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 29c41893bdbc4..3e15ed05ad645 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -1455,6 +1455,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
&CGM.getModule(), ID, {OpExpr->getType()}),
ArrayRef{OpExpr}, "hlsl.quad.read.across.y");
}
+ case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
+ Value *OpExpr = EmitScalarExpr(E->getArg(0));
+ Intrinsic::ID ID =
+ CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
+ return EmitRuntimeCall(Intrinsic::getOrInsertDeclaration(
+ &CGM.getModule(), ID, {OpExpr->getType()}),
+ ArrayRef{OpExpr}, "hlsl.quad.read.across.diagonal");
+ }
case Builtin::BI__builtin_hlsl_elementwise_sign: {
auto *Arg0 = E->getArg(0);
Value *Op0 = EmitScalarExpr(Arg0);
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index c3f3bde241b65..0c159fd1f61fc 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -160,6 +160,8 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossX, quad_read_across_x)
GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossY, quad_read_across_y)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(QuadReadAcrossDiagonal,
+ quad_read_across_diagonal)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitLow, firstbitlow)
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 62cbdb0e3ba07..9d723e49b7555 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -3740,6 +3740,105 @@ __attribute__((convergent)) double3 QuadReadAcrossY(double3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_y)
__attribute__((convergent)) double4 QuadReadAcrossY(double4);
+//===----------------------------------------------------------------------===//
+// QuadReadAcrossDiagonal builtins
+//===----------------------------------------------------------------------===//
+
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half QuadReadAcrossDiagonal(half);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half2 QuadReadAcrossDiagonal(half2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half3 QuadReadAcrossDiagonal(half3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) half4 QuadReadAcrossDiagonal(half4);
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t QuadReadAcrossDiagonal(int16_t);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t2 QuadReadAcrossDiagonal(int16_t2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t3 QuadReadAcrossDiagonal(int16_t3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int16_t4 QuadReadAcrossDiagonal(int16_t4);
+
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t QuadReadAcrossDiagonal(uint16_t);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t2 QuadReadAcrossDiagonal(uint16_t2);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t3 QuadReadAcrossDiagonal(uint16_t3);
+_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint16_t4 QuadReadAcrossDiagonal(uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int QuadReadAcrossDiagonal(int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int2 QuadReadAcrossDiagonal(int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int3 QuadReadAcrossDiagonal(int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int4 QuadReadAcrossDiagonal(int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint QuadReadAcrossDiagonal(uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint2 QuadReadAcrossDiagonal(uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint3 QuadReadAcrossDiagonal(uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint4 QuadReadAcrossDiagonal(uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t QuadReadAcrossDiagonal(int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t2 QuadReadAcrossDiagonal(int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t3 QuadReadAcrossDiagonal(int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) int64_t4 QuadReadAcrossDiagonal(int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t QuadReadAcrossDiagonal(uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t2 QuadReadAcrossDiagonal(uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t3 QuadReadAcrossDiagonal(uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) uint64_t4 QuadReadAcrossDiagonal(uint64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float QuadReadAcrossDiagonal(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float2 QuadReadAcrossDiagonal(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float3 QuadReadAcrossDiagonal(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) float4 QuadReadAcrossDiagonal(float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double QuadReadAcrossDiagonal(double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double2 QuadReadAcrossDiagonal(double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double3 QuadReadAcrossDiagonal(double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_quad_read_across_diagonal)
+__attribute__((convergent)) double4 QuadReadAcrossDiagonal(double4);
+
//===----------------------------------------------------------------------===//
// sign builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aebe284b2399a..490b56b743cdb 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4308,7 +4308,8 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
case Builtin::BI__builtin_hlsl_quad_read_across_x:
- case Builtin::BI__builtin_hlsl_quad_read_across_y: {
+ case Builtin::BI__builtin_hlsl_quad_read_across_y:
+ case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
if (SemaRef.checkArgCount(TheCall, 1))
return true;
diff --git a/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl b/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl
new file mode 100644
index 0000000000000..f89be574e8e75
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl
@@ -0,0 +1,171 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -fnative-half-type -fnative-int16-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,CHECK-DXIL,CHECK-NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL,CHECK-NO_HALF
+
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,CHECK-SPIRV,CHECK-NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV,CHECK-NO_HALF
+
+// Capture the expected interchange format so not every check needs to be duplicated
+// CHECK-DXIL: %[[RET:.*]] = call [[CC:]]i32 @llvm.[[ICF:dx]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK-SPIRV: %[[RET:.*]] = call [[CC:spir_func ]]i32 @llvm.[[ICF:spv]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK: ret i32 %[[RET]]
+int test_int(int expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v2i32(<2 x i32> %[[#]])
+// CHECK: ret <2 x i32> %[[RET]]
+int2 test_int2(int2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v3i32(<3 x i32> %[[#]])
+// CHECK: ret <3 x i32> %[[RET]]
+int3 test_int3(int3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v4i32(<4 x i32> %[[#]])
+// CHECK: ret <4 x i32> %[[RET]]
+int4 test_int4(int4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i32 @llvm.[[ICF]].quad.read.across.diagonal.i32(i32 %[[#]])
+// CHECK: ret i32 %[[RET]]
+uint test_uint(uint expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v2i32(<2 x i32> %[[#]])
+// CHECK: ret <2 x i32> %[[RET]]
+uint2 test_uint2(uint2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v3i32(<3 x i32> %[[#]])
+// CHECK: ret <3 x i32> %[[RET]]
+uint3 test_uint3(uint3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i32> @llvm.[[ICF]].quad.read.across.diagonal.v4i32(<4 x i32> %[[#]])
+// CHECK: ret <4 x i32> %[[RET]]
+uint4 test_uint4(uint4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i64 @llvm.[[ICF]].quad.read.across.diagonal.i64(i64 %[[#]])
+// CHECK: ret i64 %[[RET]]
+int64_t test_int64_t(int64_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v2i64(<2 x i64> %[[#]])
+// CHECK: ret <2 x i64> %[[RET]]
+int64_t2 test_int64_t2(int64_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v3i64(<3 x i64> %[[#]])
+// CHECK: ret <3 x i64> %[[RET]]
+int64_t3 test_int64_t3(int64_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v4i64(<4 x i64> %[[#]])
+// CHECK: ret <4 x i64> %[[RET]]
+int64_t4 test_int64_t4(int64_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]i64 @llvm.[[ICF]].quad.read.across.diagonal.i64(i64 %[[#]])
+// CHECK: ret i64 %[[RET]]
+uint64_t test_uint64_t(uint64_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<2 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v2i64(<2 x i64> %[[#]])
+// CHECK: ret <2 x i64> %[[RET]]
+uint64_t2 test_uint64_t2(uint64_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<3 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v3i64(<3 x i64> %[[#]])
+// CHECK: ret <3 x i64> %[[RET]]
+uint64_t3 test_uint64_t3(uint64_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call [[CC]]<4 x i64> @llvm.[[ICF]].quad.read.across.diagonal.v4i64(<4 x i64> %[[#]])
+// CHECK: ret <4 x i64> %[[RET]]
+uint64_t4 test_uint64_t4(uint64_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]float @llvm.[[ICF]].quad.read.across.diagonal.f32(float %[[#]])
+// CHECK: ret float %[[RET]]
+float test_float(float expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x float> @llvm.[[ICF]].quad.read.across.diagonal.v2f32(<2 x float> %[[#]])
+// CHECK: ret <2 x float> %[[RET]]
+float2 test_float2(float2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x float> @llvm.[[ICF]].quad.read.across.diagonal.v3f32(<3 x float> %[[#]])
+// CHECK: ret <3 x float> %[[RET]]
+float3 test_float3(float3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x float> @llvm.[[ICF]].quad.read.across.diagonal.v4f32(<4 x float> %[[#]])
+// CHECK: ret <4 x float> %[[RET]]
+float4 test_float4(float4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]double @llvm.[[ICF]].quad.read.across.diagonal.f64(double %[[#]])
+// CHECK: ret double %[[RET]]
+double test_double(double expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x double> @llvm.[[ICF]].quad.read.across.diagonal.v2f64(<2 x double> %[[#]])
+// CHECK: ret <2 x double> %[[RET]]
+double2 test_double2(double2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x double> @llvm.[[ICF]].quad.read.across.diagonal.v3f64(<3 x double> %[[#]])
+// CHECK: ret <3 x double> %[[RET]]
+double3 test_double3(double3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x double> @llvm.[[ICF]].quad.read.across.diagonal.v4f64(<4 x double> %[[#]])
+// CHECK: ret <4 x double> %[[RET]]
+double4 test_double4(double4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]half @llvm.[[ICF]].quad.read.across.diagonal.f16(half %[[#]])
+// CHECK-NATIVE_HALF: ret half %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]float @llvm.[[ICF]].quad.read.across.diagonal.f32(float %[[#]])
+// CHECK-NO_HALF: ret float %[[RET]]
+half test_half(half expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x half> @llvm.[[ICF]].quad.read.across.diagonal.v2f16(<2 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<2 x float> @llvm.[[ICF]].quad.read.across.diagonal.v2f32(<2 x float> %[[#]])
+// CHECK-NO_HALF: ret <2 x float> %[[RET]]
+half2 test_half2(half2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x half> @llvm.[[ICF]].quad.read.across.diagonal.v3f16(<3 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<3 x float> @llvm.[[ICF]].quad.read.across.diagonal.v3f32(<3 x float> %[[#]])
+// CHECK-NO_HALF: ret <3 x float> %[[RET]]
+half3 test_half3(half3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x half> @llvm.[[ICF]].quad.read.across.diagonal.v4f16(<4 x half> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x half> %[[RET]]
+// CHECK-NO_HALF: %[[RET:.*]] = call reassoc nnan ninf nsz arcp afn [[CC]]<4 x float> @llvm.[[ICF]].quad.read.across.diagonal.v4f32(<4 x float> %[[#]])
+// CHECK-NO_HALF: ret <4 x float> %[[RET]]
+half4 test_half4(half4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+#ifdef __HLSL_ENABLE_16_BIT
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]i16 @llvm.[[ICF]].quad.read.across.diagonal.i16(i16 %[[#]])
+// CHECK-NATIVE_HALF: ret i16 %[[RET]]
+int16_t test_int16_t(int16_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<2 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v2i16(<2 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x i16> %[[RET]]
+int16_t2 test_int16_t2(int16_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<3 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v3i16(<3 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x i16> %[[RET]]
+int16_t3 test_int16_t3(int16_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<4 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v4i16(<4 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x i16> %[[RET]]
+int16_t4 test_int16_t4(int16_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]i16 @llvm.[[ICF]].quad.read.across.diagonal.i16(i16 %[[#]])
+// CHECK-NATIVE_HALF: ret i16 %[[RET]]
+uint16_t test_uint16_t(uint16_t expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<2 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v2i16(<2 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <2 x i16> %[[RET]]
+uint16_t2 test_uint16_t2(uint16_t2 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<3 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v3i16(<3 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <3 x i16> %[[RET]]
+uint16_t3 test_uint16_t3(uint16_t3 expr) { return QuadReadAcrossDiagonal(expr); }
+
+// CHECK-NATIVE_HALF: %[[RET:.*]] = call [[CC]]<4 x i16> @llvm.[[ICF]].quad.read.across.diagonal.v4i16(<4 x i16> %[[#]])
+// CHECK-NATIVE_HALF: ret <4 x i16> %[[RET]]
+uint16_t4 test_uint16_t4(uint16_t4 expr) { return QuadReadAcrossDiagonal(expr); }
+#endif
diff --git a/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl
new file mode 100644
index 0000000000000..322eacd7ca798
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -finclude-defau...
[truncated]
|
s-perron
left a comment
There was a problem hiding this comment.
The SPIR-V code looks good. Just update the test to target vulkan 1.3 and use the target env when calling spirv-val.
636dd64 to
7defcbe
Compare
Just curious here, why isn't this a case where we'd add the scalar block layout option? |
86c880e to
c7cded9
Compare
|
Can you fix the merge conflict @kcloudy0717 ? |
Sure I can fix the merge conflicts. |
c7cded9 to
6da8914
Compare
|
@bob80905 Conflicts resolved, rebased to latest commit. |
6da8914 to
4f1106a
Compare
4f1106a to
b4dc809
Compare
b4dc809 to
a79b7a6
Compare
a79b7a6 to
bfb12b1
Compare
bogner
left a comment
There was a problem hiding this comment.
This has been sitting for a while - do you need somebody to merge it for you?
I think you've made enough changes that folks were assuming you have commit access at this point - you can feel free to request it following the guidelines here: https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access. Feel free to CC me to give an approval.
Yea, could you merge it for me? I still don't have access to the repo, and I wasn't sure what requirements are needed to gain access. I will now apply for the access, thank you :) |
|
I've merged it and put up the XFAIL update here: llvm/offload-test-suite#1316 |
These are resolved as of llvm/llvm-project#188567
…8567) This PR adds QuadReadAcrossDiagonal intrinsic support in HLSL with codegen for both DirectX and SPIRV backends. Resolves llvm#99177. - [x] Implement `QuadReadAcrossDiagonal` clang builtin - [x] Link `QuadReadAcrossDiagonal` clang builtin with `hlsl_intrinsics.h` - [x] Add sema checks for `QuadReadAcrossDiagonal` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp` - [x] Add codegen for `QuadReadAcrossDiagonal` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp` - [x] Add codegen tests to `clang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlsl` - [x] Add sema tests to `clang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlsl` - [x] Create the `int_dx_QuadReadAcrossDiagonal` intrinsic in `IntrinsicsDirectX.td` - [x] Create the `DXILOpMapping` of `int_dx_QuadReadAcrossDiagonal` to `123` in `DXIL.td` - [x] Create the `QuadReadAcrossDiagonal.ll` and `QuadReadAcrossDiagonal_errors.ll` tests in `llvm/test/CodeGen/DirectX/` - [x] Create the `int_spv_QuadReadAcrossDiagonal` intrinsic in `IntrinsicsSPIRV.td` - [x] In SPIRVInstructionSelector.cpp create the `QuadReadAcrossDiagonal` lowering and map it to `int_spv_QuadReadAcrossDiagonal` in `SPIRVInstructionSelector::selectIntrinsic`. - [x] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadReadAcrossDiagonal.ll` --------- Co-authored-by: Justin Bogner <mail@justinbogner.com>
These are resolved as of llvm/llvm-project#188567
This PR adds QuadReadAcrossDiagonal intrinsic support in HLSL with codegen for both DirectX and SPIRV backends. Resolves #99177.
QuadReadAcrossDiagonalclang builtinQuadReadAcrossDiagonalclang builtin withhlsl_intrinsics.hQuadReadAcrossDiagonaltoCheckHLSLBuiltinFunctionCallinSemaChecking.cppQuadReadAcrossDiagonaltoEmitHLSLBuiltinExprinCGBuiltin.cppclang/test/CodeGenHLSL/builtins/QuadReadAcrossDiagonal.hlslclang/test/SemaHLSL/BuiltIns/QuadReadAcrossDiagonal-errors.hlslint_dx_QuadReadAcrossDiagonalintrinsic inIntrinsicsDirectX.tdDXILOpMappingofint_dx_QuadReadAcrossDiagonalto123inDXIL.tdQuadReadAcrossDiagonal.llandQuadReadAcrossDiagonal_errors.lltests inllvm/test/CodeGen/DirectX/int_spv_QuadReadAcrossDiagonalintrinsic inIntrinsicsSPIRV.tdQuadReadAcrossDiagonallowering and map it toint_spv_QuadReadAcrossDiagonalinSPIRVInstructionSelector::selectIntrinsic.llvm/test/CodeGen/SPIRV/hlsl-intrinsics/QuadReadAcrossDiagonal.ll