llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Kaitlin Peng (kmpeng)

<details>
<summary>Changes</summary>

Closes #<!-- -->184513.

This PR implements the matrix api for `pow` in `HLSLintrinsics.td`, adds matrix 
codegen tests, matrix sema tests, and matrix backend tests.

---

Patch is 50.11 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/212514.diff


8 Files Affected:

- (modified) clang/include/clang/Basic/HLSLIntrinsics.td (-1) 
- (modified) clang/lib/Headers/hlsl/hlsl_compat_overloads.h (+2) 
- (added) clang/test/CodeGenHLSL/builtins/pow_mat-overloads.hlsl (+52) 
- (added) clang/test/CodeGenHLSL/builtins/pow_mat.hlsl (+203) 
- (modified) clang/test/SemaHLSL/BuiltIns/binary-compat-overload-warnings.hlsl 
(+1-1) 
- (added) clang/test/SemaHLSL/BuiltIns/pow_mat-errors.hlsl (+7) 
- (added) llvm/test/CodeGen/DirectX/pow_mat.ll (+47) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pow_mat.ll (+551) 


``````````diff
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td 
b/clang/include/clang/Basic/HLSLIntrinsics.td
index 99259046940f1..331f87bddbcca 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -1319,7 +1319,6 @@ def hlsl_pow : HLSLTwoArgBuiltin<"pow", 
"__builtin_elementwise_pow"> {
 \param Pow The specified power.
 }];
   let VaryingTypes = [HalfTy, FloatTy];
-  let VaryingMatDims = [];
 }
 
 // Reads the value from the lane across the X axis of the quad.
diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h 
b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index d97039128ea85..3a75050129aa5 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -484,6 +484,8 @@ _DXC_COMPAT_UNARY_INTEGER_OVERLOADS(normalize)
 
 _DXC_COMPAT_BINARY_DOUBLE_OVERLOADS(pow)
 _DXC_COMPAT_BINARY_INTEGER_OVERLOADS(pow)
+_DXC_COMPAT_BINARY_DOUBLE_MATRIX_OVERLOADS(pow)
+_DXC_COMPAT_BINARY_INTEGER_MATRIX_OVERLOADS(pow)
 
 
//===----------------------------------------------------------------------===//
 // rsqrt builtins overloads
diff --git a/clang/test/CodeGenHLSL/builtins/pow_mat-overloads.hlsl 
b/clang/test/CodeGenHLSL/builtins/pow_mat-overloads.hlsl
new file mode 100644
index 0000000000000..4910f096d86f8
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/pow_mat-overloads.hlsl
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm  \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK -DSPIR_FUNC="" 
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-library %s -emit-llvm  \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK -DSPIR_FUNC="spir_func "
+
+
+// CHECK: define hidden [[SPIR_FUNC]]noundef nofpclass(nan inf) <12 x float> 
@_{{.*}}test_pow_double3x4{{.*}}(
+// CHECK:    [[CONVI:%.*]] = fptrunc {{.*}} <12 x double> %{{.*}} to <12 x 
float>
+// CHECK:    [[CONV1I:%.*]] = fptrunc {{.*}} <12 x double> %{{.*}} to <12 x 
float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <12 x float> @llvm.pow.v12f32(<12 x 
float> [[CONVI]], <12 x float> [[CONV1I]])
+// CHECK:    ret <12 x float> [[V5]]
+float3x4 test_pow_double3x4 (double3x4 p0, double3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK: define hidden [[SPIR_FUNC]]noundef nofpclass(nan inf) <12 x float> 
@_{{.*}}test_pow_uint3x4{{.*}}(
+// CHECK:    [[CONVI:%.*]] = uitofp {{.*}} <12 x i32> %{{.*}} to <12 x float>
+// CHECK:    [[CONV1I:%.*]] = uitofp {{.*}} <12 x i32> %{{.*}} to <12 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <12 x float> @llvm.pow.v12f32(<12 x 
float> [[CONVI]], <12 x float> [[CONV1I]])
+// CHECK:    ret <12 x float> [[V5]]
+float3x4 test_pow_uint3x4 (uint3x4 p0, uint3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK: define hidden [[SPIR_FUNC]]noundef nofpclass(nan inf) <12 x float> 
@_{{.*}}test_pow_int3x4{{.*}}(
+// CHECK:    [[CONVI:%.*]] = sitofp {{.*}} <12 x i32> %{{.*}} to <12 x float>
+// CHECK:    [[CONV1I:%.*]] = sitofp {{.*}} <12 x i32> %{{.*}} to <12 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <12 x float> @llvm.pow.v12f32(<12 x 
float> [[CONVI]], <12 x float> [[CONV1I]])
+// CHECK:    ret <12 x float> [[V5]]
+float3x4 test_pow_int3x4 (int3x4 p0, int3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK: define hidden [[SPIR_FUNC]]noundef nofpclass(nan inf) <12 x float> 
@_{{.*}}test_pow_int64_t3x4{{.*}}(
+// CHECK:    [[CONVI:%.*]] = sitofp {{.*}} <12 x i64> %{{.*}} to <12 x float>
+// CHECK:    [[CONV1I:%.*]] = sitofp {{.*}} <12 x i64> %{{.*}} to <12 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <12 x float> @llvm.pow.v12f32(<12 x 
float> [[CONVI]], <12 x float> [[CONV1I]])
+// CHECK:    ret <12 x float> [[V5]]
+float3x4 test_pow_int64_t3x4 (int64_t3x4 p0, int64_t3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK: define hidden [[SPIR_FUNC]]noundef nofpclass(nan inf) <12 x float> 
@_{{.*}}test_pow_uint64_t3x4{{.*}}(
+// CHECK:    [[CONVI:%.*]] = uitofp {{.*}} <12 x i64> %{{.*}} to <12 x float>
+// CHECK:    [[CONV1I:%.*]] = uitofp {{.*}} <12 x i64> %{{.*}} to <12 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <12 x float> @llvm.pow.v12f32(<12 x 
float> [[CONVI]], <12 x float> [[CONV1I]])
+// CHECK:    ret <12 x float> [[V5]]
+float3x4 test_pow_uint64_t3x4 (uint64_t3x4 p0, uint64_t3x4 p1) {
+  return pow(p0, p1);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/pow_mat.hlsl 
b/clang/test/CodeGenHLSL/builtins/pow_mat.hlsl
new file mode 100644
index 0000000000000..1877888189518
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/pow_mat.hlsl
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type 
-fnative-int16-type \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN:   --check-prefixes=CHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF
+
+// CHECK-LABEL: test_pow_half1x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.pow.v2f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32
+half1x2 test_pow_half1x2 (half1x2 p0, half1x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half1x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.pow.v3f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32
+half1x3 test_pow_half1x3 (half1x3 p0, half1x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half1x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.pow.v4f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+half1x4 test_pow_half1x4 (half1x4 p0, half1x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half2x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.pow.v2f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32
+half2x1 test_pow_half2x1 (half2x1 p0, half2x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half2x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.pow.v4f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+half2x2 test_pow_half2x2 (half2x2 p0, half2x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half2x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <6 x half> @llvm.pow.v6f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.pow.v6f32
+half2x3 test_pow_half2x3 (half2x3 p0, half2x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half2x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <8 x half> @llvm.pow.v8f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.pow.v8f32
+half2x4 test_pow_half2x4 (half2x4 p0, half2x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half3x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.pow.v3f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32
+half3x1 test_pow_half3x1 (half3x1 p0, half3x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half3x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <6 x half> @llvm.pow.v6f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.pow.v6f32
+half3x2 test_pow_half3x2 (half3x2 p0, half3x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half3x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <9 x half> @llvm.pow.v9f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <9 x float> @llvm.pow.v9f32
+half3x3 test_pow_half3x3 (half3x3 p0, half3x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half3x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <12 x half> 
@llvm.pow.v12f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.pow.v12f32
+half3x4 test_pow_half3x4 (half3x4 p0, half3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half4x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.pow.v4f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+half4x1 test_pow_half4x1 (half4x1 p0, half4x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half4x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <8 x half> @llvm.pow.v8f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.pow.v8f32
+half4x2 test_pow_half4x2 (half4x2 p0, half4x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half4x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <12 x half> 
@llvm.pow.v12f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.pow.v12f32
+half4x3 test_pow_half4x3 (half4x3 p0, half4x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_half4x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <16 x half> 
@llvm.pow.v16f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.pow.v16f32
+half4x4 test_pow_half4x4 (half4x4 p0, half4x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float1x2
+// CHECK:  call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32
+float1x2 test_pow_float1x2 (float1x2 p0, float1x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float1x3
+// CHECK:  call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32
+float1x3 test_pow_float1x3 (float1x3 p0, float1x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float1x4
+// CHECK:  call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+float1x4 test_pow_float1x4 (float1x4 p0, float1x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float2x1
+// CHECK:  call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32
+float2x1 test_pow_float2x1 (float2x1 p0, float2x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float2x2
+// CHECK:  call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+float2x2 test_pow_float2x2 (float2x2 p0, float2x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float2x3
+// CHECK:  call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.pow.v6f32
+float2x3 test_pow_float2x3 (float2x3 p0, float2x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float2x4
+// CHECK:  call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.pow.v8f32
+float2x4 test_pow_float2x4 (float2x4 p0, float2x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float3x1
+// CHECK:  call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32
+float3x1 test_pow_float3x1 (float3x1 p0, float3x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float3x2
+// CHECK:  call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.pow.v6f32
+float3x2 test_pow_float3x2 (float3x2 p0, float3x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float3x3
+// CHECK:  call reassoc nnan ninf nsz arcp afn <9 x float> @llvm.pow.v9f32
+float3x3 test_pow_float3x3 (float3x3 p0, float3x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float3x4
+// CHECK:  call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.pow.v12f32
+float3x4 test_pow_float3x4 (float3x4 p0, float3x4 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float4x1
+// CHECK:  call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32
+float4x1 test_pow_float4x1 (float4x1 p0, float4x1 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float4x2
+// CHECK:  call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.pow.v8f32
+float4x2 test_pow_float4x2 (float4x2 p0, float4x2 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float4x3
+// CHECK:  call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.pow.v12f32
+float4x3 test_pow_float4x3 (float4x3 p0, float4x3 p1) {
+  return pow(p0, p1);
+}
+
+// CHECK-LABEL: test_pow_float4x4
+// CHECK:  call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.pow.v16f32
+float4x4 test_pow_float4x4 (float4x4 p0, float4x4 p1) {
+  return pow(p0, p1);
+}
+
diff --git a/clang/test/SemaHLSL/BuiltIns/binary-compat-overload-warnings.hlsl 
b/clang/test/SemaHLSL/BuiltIns/binary-compat-overload-warnings.hlsl
index e798acbf67dd2..d521e7f7dd5c0 100644
--- a/clang/test/SemaHLSL/BuiltIns/binary-compat-overload-warnings.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/binary-compat-overload-warnings.hlsl
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -finclude-default-header -triple 
dxilv1.0-unknown-shadermodel6.0-library -std=hlsl202x -emit-llvm-only 
-disable-llvm-passes -DFUNC=atan2 %s 2>&1 | FileCheck %s -DFUNC=atan2 
--check-prefixes=CHECK,CHECK-MAT
-// RUN: %clang_cc1 -finclude-default-header -triple 
dxilv1.0-unknown-shadermodel6.0-library -std=hlsl202x -emit-llvm-only 
-disable-llvm-passes -DFUNC=pow %s 2>&1 | FileCheck %s -DFUNC=pow
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxilv1.0-unknown-shadermodel6.0-library -std=hlsl202x -emit-llvm-only 
-disable-llvm-passes -DFUNC=pow %s 2>&1 | FileCheck %s -DFUNC=pow 
--check-prefixes=CHECK,CHECK-MAT
 // RUN: %clang_cc1 -finclude-default-header -triple 
dxilv1.0-unknown-shadermodel6.0-library -std=hlsl202x -emit-llvm-only 
-disable-llvm-passes -DFUNC=step %s 2>&1 | FileCheck %s -DFUNC=step
 
 // binary double overloads
diff --git a/clang/test/SemaHLSL/BuiltIns/pow_mat-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/pow_mat-errors.hlsl
new file mode 100644
index 0000000000000..ca01f8ee70214
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/pow_mat-errors.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type 
-emit-llvm-only -disable-llvm-passes -verify
+
+
+double2x2 test_vec_double_builtin(double2x2 p0, double2x2 p1) {
+    return __builtin_elementwise_pow(p0, p1);
+  // expected-error@-1 {{1st argument must be a scalar or vector of 16 or 32 
bit floating-point types (was 'double2x2' (aka 'matrix<double, 2, 2>'))}}
+}
diff --git a/llvm/test/CodeGen/DirectX/pow_mat.ll 
b/llvm/test/CodeGen/DirectX/pow_mat.ll
new file mode 100644
index 0000000000000..cf095a60d51de
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/pow_mat.ll
@@ -0,0 +1,47 @@
+; RUN: opt -S -dxil-intrinsic-expansion 
-mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s 
--check-prefix=EXPCHECK
+; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower 
-mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s 
--check-prefix=DOPCHECK
+
+; Make sure correct dxil expansions for pow are generated for float and half.
+
+define noundef <16 x half> @pow_half4x4(<16 x half> noundef %a, <16 x half> 
noundef %b) {
+entry:
+; Just Expansion, no scalarization or lowering:
+; EXPCHECK: [[LOG2:%.+]] = call <16 x half> @llvm.log2.v16f16(<16 x half> %a)
+; EXPCHECK: [[MUL:%.+]] = fmul <16 x half> [[LOG2]], %b
+; EXPCHECK: [[EXP2:%.+]] = call <16 x half> @llvm.exp2.v16f16(<16 x half> 
[[MUL]])
+; EXPCHECK: ret <16 x half> [[EXP2]]
+
+; Scalarization occurs after expansion, so log2/exp2 scalarization is tested 
separately.
+; Expansion, scalarization and lowering:
+; Just make sure this expands to exactly 16 scalar DXIL log2 (OpCode=23) and 
16 scalar DXIL exp2 (OpCode=21) calls.
+; DOPCHECK-COUNT-16: call half @dx.op.unary.f16(i32 23, half %{{.*}})
+; DOPCHECK-NOT: call half @dx.op.unary.f16(i32 23,
+; DOPCHECK-COUNT-16: call half @dx.op.unary.f16(i32 21, half %{{.*}})
+; DOPCHECK-NOT: call half @dx.op.unary.f16(i32 21,
+
+  %elt.pow = call <16 x half> @llvm.pow.v16f16(<16 x half> %a, <16 x half> %b)
+  ret <16 x half> %elt.pow
+}
+
+define noundef <16 x float> @pow_float4x4(<16 x float> noundef %a, <16 x 
float> noundef %b) {
+entry:
+; Just Expansion, no scalarization or lowering:
+; EXPCHECK: [[LOG2:%.+]] = call <16 x float> @llvm.log2.v16f32(<16 x float> %a)
+; EXPCHECK: [[MUL:%.+]] = fmul <16 x float> [[LOG2]], %b
+; EXPCHECK: [[EXP2:%.+]] = call <16 x float> @llvm.exp2.v16f32(<16 x float> 
[[MUL]])
+; EXPCHECK: ret <16 x float> [[EXP2]]
+
+; Scalarization occurs after expansion, so log2/exp2 scalarization is tested 
separately.
+; Expansion, scalarization and lowering:
+; Just make sure this expands to exactly 16 scalar DXIL log2 (OpCode=23) and 
16 scalar DXIL exp2 (OpCode=21) calls.
+; DOPCHECK-COUNT-16: call float @dx.op.unary.f32(i32 23, float %{{.*}})
+; DOPCHECK-NOT: call float @dx.op.unary.f32(i32 23,
+; DOPCHECK-COUNT-16: call float @dx.op.unary.f32(i32 21, float %{{.*}})
+; DOPCHECK-NOT: call float @dx.op.unary.f32(i32 21,
+
+  %elt.pow = call <16 x float> @llvm.pow.v16f32(<16 x float> %a, <16 x float> 
%b)
+  ret <16 x float> %elt.pow
+}
+
+declare <16 x half> @llvm.pow.v16f16(<16 x half>, <16 x half>)
+declare <16 x float> @llvm.pow.v16f32(<16 x float>, <16 x float>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pow_mat.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pow_mat.ll
new file mode 100644
index 0000000000000..777017ecc6efc
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/pow_mat.ll
@@ -0,0 +1,551 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - 
-filetype=obj | spirv-val %}
+
+; Vulkan/Shader does not allow the Vector16 capability, so an MxN HLSL matrix
+; is represented as [M x <N x float>] in LLVM IR and elementwise pow is
+; computed per-row as M OpExtInst Pow calls on <N x float> (and similarly
+; for half). Matrices with N=3 exercise the legalizer's handling of
+; non-power-of-2 vector widths (legal for shader via allShaderFloatVectors).
+
+; CHECK-NOT: OpCapability Vector16
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#void:]] = OpTypeVoid
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#vec3_float_32:]] = OpTypeVector %[[#float_32]] 3
+; CHECK-DAG: %[[#vec3_float_16:]] = OpTypeVector %[[#float_16]] 3
+; CHECK-DAG: %[[#vec2_float_32:]] = OpTypeVector %[[#float_32]] 2
+; CHECK-DAG: %[[#vec2_float_16:]] = OpTypeVector %[[#float_16]] 2
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#const_0:]] = OpConstant %[[#int_32]] 0
+; CHECK-DAG: %[[#const_1:]] = OpConstant %[[#int_32]] 1
+; CHECK-DAG: %[[#const_2:]] = OpConstant %[[#int_32]] 2
+; CHECK-DAG: %[[#const_3:]] = OpConstant %[[#int_32]] 3
+; CHECK-DAG: %[[#const_4:]] = OpConstant %[[#int_32]] 4
+; CHECK-DAG: %[[#arr_f32:]] = OpTypeArray %[[#vec4_float_32]] %[[#const_4]]
+; CHECK-DAG: %[[#arr_f16:]] = OpTypeArray %[[#vec4_float_16]] %[[#const_4]]
+; CHECK-DAG: %[[#arr3_f32:]] = OpTypeArray %[[#vec3_float_32]] %[[#const_3]]
+; CHECK-DAG: %[[#arr3_f16:]] = OpTypeArray %[[#vec3_float_16]] %[[#const_3]]
+; CHECK-DAG: %[[#ptr_arr_f32:]] = OpTypePointer Private %[[#arr_f32]]
+; CHECK-DAG: %[[#ptr_arr_f16:]] = OpTypePointer Private %[[#arr_f16]]
+; CHECK-DAG: %[[#ptr_arr3_f32:]] = OpTypePointer Private %[[#arr3_f32]]
+; CHECK-DAG: %[[#ptr_arr3_f16:]] = OpTypePointer Private %[[#arr3_f16]]
+; CHECK-DAG: %[[#ptr_vec4_f32:]] = OpTypePointer Private %[[#vec4_float_32]]
+; CHECK-DAG: %[[#ptr_vec4_f16:]] = OpTypePointer Private %[[#vec4_float_16]]
+; CHECK-DAG: %[[#ptr_vec3_f32:]] = OpTypePointer Private %[[#vec3_float_32]]
+; CHECK-DAG: %[[#ptr_vec3_f16:]] = OpTypePointer Private %[[#vec3_float_16]]
+; CHECK-DAG: %[[#fn_f32:]] = OpTypeFunction %[[#void]] %[[#ptr_arr_f32]] 
%[[#ptr_arr_f32]] %[[#ptr_arr_f32]]
+; CHECK-DAG: %[[#fn_f16:]] = OpTypeFunction %[[#void]] %[[#ptr_arr_f16]] 
%[[#ptr_arr_f16]] %[[#ptr_arr_f16]]
+; CHECK-DAG: %[[#fn3_f32:]] = OpTypeFunction %[[#void]] %[[#ptr_arr3_f32]] 
%[[#ptr_arr3_f32]] %[[#ptr_arr3_f32]]
+; CHECK-DAG: %[[#fn3_f16:]] = OpTypeFunction %[[#void]] %[[#ptr_arr3_f16]] 
%[[#ptr_arr3_f16]] %[[#ptr_arr3_f16]]
+
+define internal void @pow_float4x4(ptr addrspace(10) %out, ptr addrspace(10) 
%a, ptr addrspace(10) %b) {
+entry:
+  ; CHECK: OpFunction %[[#void]] None %[[#fn_f32]]
+  ; CHECK: %[[#out_f32:]] = OpFunctionParameter %[[#ptr_arr_f32]]
+  ; CHECK: %[[#a_f32:]] = OpFunctionParameter %[[#ptr_arr_f32]]
+  ; CHECK: %[[#b_f32:]] = OpFunctionParameter %[[#ptr_arr_f32]]
+  ; CHECK: %[[#a0_ptr_f32:]] = OpAccessChain %[[#ptr_vec4_f32]] %[[#a_f32]] 
%[[#const_0]]
+  ; CHECK: %[[#a1_ptr_f32:]] = OpAccessChain ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/212514
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to