[clang] [llvm] [Matrix] Implement matrix support for the `abs` intrinsic (PR #227131)
Kaitlin Peng via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 28 14:50:40 PDT 2026
https://github.com/kmpeng created https://github.com/llvm/llvm-project/pull/227131
Closes #184491.
This PR implements the matrix api for `abs` in `HLSLintrinsics.td`, adds matrix codegen tests, matrix sema tests, and SPIRV matrix backend tests. DirectX matrix backend tests were not added because no DirectX backend changes were made.
Assisted-by: Claude Opus 4.8
>From f1b52bb09d010a55724926859cc9811c21b29117 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Tue, 22 Sep 2026 19:43:11 -0700
Subject: [PATCH] abs matrix implementation and tests
---
clang/include/clang/Basic/HLSLIntrinsics.td | 2 -
clang/lib/CodeGen/CGBuiltin.cpp | 2 +
clang/test/CodeGenHLSL/builtins/abs_mat.hlsl | 564 ++++++++++++++++++
.../SemaHLSL/BuiltIns/abs_mat-errors.hlsl | 22 +
llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp | 1 +
.../CodeGen/SPIRV/hlsl-intrinsics/abs_mat.ll | 115 ++++
6 files changed, 704 insertions(+), 2 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/builtins/abs_mat.hlsl
create mode 100644 clang/test/SemaHLSL/BuiltIns/abs_mat-errors.hlsl
create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/abs_mat.ll
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index f067d060d5a2d..d0a8d5b456a99 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -326,7 +326,6 @@ def hlsl_abs : HLSLOneArgBuiltin<"abs", "__builtin_elementwise_abs"> {
}];
let VaryingTypes = SignedTypes;
let VaryingLongVector = 1;
- let VaryingMatDims = [];
}
// Unsigned abs is a constexpr identity - unsigned values are already non-negative.
@@ -344,7 +343,6 @@ function returns its input unchanged.
let IsConstexpr = 1;
let VaryingTypes = UnsignedIntTypes;
let VaryingLongVector = 1;
- let VaryingMatDims = [];
}
// Returns the arccosine of the input value, Val.
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f500162532777..233609605fb21 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4351,6 +4351,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
if (auto *VecTy = QT->getAs<VectorType>())
QT = VecTy->getElementType();
+ else if (auto *MatTy = QT->getAs<ConstantMatrixType>())
+ QT = MatTy->getElementType();
if (QT->isIntegerType())
Result = Builder.CreateBinaryIntrinsic(
Intrinsic::abs, EmitScalarExpr(E->getArg(0)), Builder.getFalse(),
diff --git a/clang/test/CodeGenHLSL/builtins/abs_mat.hlsl b/clang/test/CodeGenHLSL/builtins/abs_mat.hlsl
new file mode 100644
index 0000000000000..ec5c7b4a98689
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/abs_mat.hlsl
@@ -0,0 +1,564 @@
+// 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
+
+#ifdef __HLSL_ENABLE_16_BIT
+// NATIVE_HALF-LABEL: test_abs_short1x2
+// NATIVE_HALF: call <2 x i16> @llvm.abs.v2i16(<2 x i16> %{{.*}}, i1 false)
+int16_t1x2 test_abs_short1x2(int16_t1x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short1x3
+// NATIVE_HALF: call <3 x i16> @llvm.abs.v3i16(<3 x i16> %{{.*}}, i1 false)
+int16_t1x3 test_abs_short1x3(int16_t1x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short1x4
+// NATIVE_HALF: call <4 x i16> @llvm.abs.v4i16(<4 x i16> %{{.*}}, i1 false)
+int16_t1x4 test_abs_short1x4(int16_t1x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short2x1
+// NATIVE_HALF: call <2 x i16> @llvm.abs.v2i16(<2 x i16> %{{.*}}, i1 false)
+int16_t2x1 test_abs_short2x1(int16_t2x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short2x2
+// NATIVE_HALF: call <4 x i16> @llvm.abs.v4i16(<4 x i16> %{{.*}}, i1 false)
+int16_t2x2 test_abs_short2x2(int16_t2x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short2x3
+// NATIVE_HALF: call <6 x i16> @llvm.abs.v6i16(<6 x i16> %{{.*}}, i1 false)
+int16_t2x3 test_abs_short2x3(int16_t2x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short2x4
+// NATIVE_HALF: call <8 x i16> @llvm.abs.v8i16(<8 x i16> %{{.*}}, i1 false)
+int16_t2x4 test_abs_short2x4(int16_t2x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short3x1
+// NATIVE_HALF: call <3 x i16> @llvm.abs.v3i16(<3 x i16> %{{.*}}, i1 false)
+int16_t3x1 test_abs_short3x1(int16_t3x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short3x2
+// NATIVE_HALF: call <6 x i16> @llvm.abs.v6i16(<6 x i16> %{{.*}}, i1 false)
+int16_t3x2 test_abs_short3x2(int16_t3x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short3x3
+// NATIVE_HALF: call <9 x i16> @llvm.abs.v9i16(<9 x i16> %{{.*}}, i1 false)
+int16_t3x3 test_abs_short3x3(int16_t3x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short3x4
+// NATIVE_HALF: call <12 x i16> @llvm.abs.v12i16(<12 x i16> %{{.*}}, i1 false)
+int16_t3x4 test_abs_short3x4(int16_t3x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short4x1
+// NATIVE_HALF: call <4 x i16> @llvm.abs.v4i16(<4 x i16> %{{.*}}, i1 false)
+int16_t4x1 test_abs_short4x1(int16_t4x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short4x2
+// NATIVE_HALF: call <8 x i16> @llvm.abs.v8i16(<8 x i16> %{{.*}}, i1 false)
+int16_t4x2 test_abs_short4x2(int16_t4x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short4x3
+// NATIVE_HALF: call <12 x i16> @llvm.abs.v12i16(<12 x i16> %{{.*}}, i1 false)
+int16_t4x3 test_abs_short4x3(int16_t4x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_short4x4
+// NATIVE_HALF: call <16 x i16> @llvm.abs.v16i16(<16 x i16> %{{.*}}, i1 false)
+int16_t4x4 test_abs_short4x4(int16_t4x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort1x2
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t1x2 test_abs_ushort1x2(uint16_t1x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort1x3
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t1x3 test_abs_ushort1x3(uint16_t1x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort1x4
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t1x4 test_abs_ushort1x4(uint16_t1x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort2x1
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t2x1 test_abs_ushort2x1(uint16_t2x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort2x2
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t2x2 test_abs_ushort2x2(uint16_t2x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort2x3
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t2x3 test_abs_ushort2x3(uint16_t2x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort2x4
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t2x4 test_abs_ushort2x4(uint16_t2x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort3x1
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t3x1 test_abs_ushort3x1(uint16_t3x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort3x2
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t3x2 test_abs_ushort3x2(uint16_t3x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort3x3
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t3x3 test_abs_ushort3x3(uint16_t3x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort3x4
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t3x4 test_abs_ushort3x4(uint16_t3x4 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort4x1
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t4x1 test_abs_ushort4x1(uint16_t4x1 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort4x2
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t4x2 test_abs_ushort4x2(uint16_t4x2 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort4x3
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t4x3 test_abs_ushort4x3(uint16_t4x3 p0) { return abs(p0); }
+
+// NATIVE_HALF-LABEL: test_abs_ushort4x4
+// NATIVE_HALF: call {{.*}} @{{.*}}hlsl3abs
+uint16_t4x4 test_abs_ushort4x4(uint16_t4x4 p0) { return abs(p0); }
+#endif
+
+// CHECK-LABEL: test_abs_int1x2
+// CHECK: call <2 x i32> @llvm.abs.v2i32(<2 x i32> %{{.*}}, i1 false)
+int1x2 test_abs_int1x2(int1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int1x3
+// CHECK: call <3 x i32> @llvm.abs.v3i32(<3 x i32> %{{.*}}, i1 false)
+int1x3 test_abs_int1x3(int1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int1x4
+// CHECK: call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false)
+int1x4 test_abs_int1x4(int1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int2x1
+// CHECK: call <2 x i32> @llvm.abs.v2i32(<2 x i32> %{{.*}}, i1 false)
+int2x1 test_abs_int2x1(int2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int2x2
+// CHECK: call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false)
+int2x2 test_abs_int2x2(int2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int2x3
+// CHECK: call <6 x i32> @llvm.abs.v6i32(<6 x i32> %{{.*}}, i1 false)
+int2x3 test_abs_int2x3(int2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int2x4
+// CHECK: call <8 x i32> @llvm.abs.v8i32(<8 x i32> %{{.*}}, i1 false)
+int2x4 test_abs_int2x4(int2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int3x1
+// CHECK: call <3 x i32> @llvm.abs.v3i32(<3 x i32> %{{.*}}, i1 false)
+int3x1 test_abs_int3x1(int3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int3x2
+// CHECK: call <6 x i32> @llvm.abs.v6i32(<6 x i32> %{{.*}}, i1 false)
+int3x2 test_abs_int3x2(int3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int3x3
+// CHECK: call <9 x i32> @llvm.abs.v9i32(<9 x i32> %{{.*}}, i1 false)
+int3x3 test_abs_int3x3(int3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int3x4
+// CHECK: call <12 x i32> @llvm.abs.v12i32(<12 x i32> %{{.*}}, i1 false)
+int3x4 test_abs_int3x4(int3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int4x1
+// CHECK: call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false)
+int4x1 test_abs_int4x1(int4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int4x2
+// CHECK: call <8 x i32> @llvm.abs.v8i32(<8 x i32> %{{.*}}, i1 false)
+int4x2 test_abs_int4x2(int4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int4x3
+// CHECK: call <12 x i32> @llvm.abs.v12i32(<12 x i32> %{{.*}}, i1 false)
+int4x3 test_abs_int4x3(int4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_int4x4
+// CHECK: call <16 x i32> @llvm.abs.v16i32(<16 x i32> %{{.*}}, i1 false)
+int4x4 test_abs_int4x4(int4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint1x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint1x2 test_abs_uint1x2(uint1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint1x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint1x3 test_abs_uint1x3(uint1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint1x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint1x4 test_abs_uint1x4(uint1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint2x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint2x1 test_abs_uint2x1(uint2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint2x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint2x2 test_abs_uint2x2(uint2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint2x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint2x3 test_abs_uint2x3(uint2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint2x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint2x4 test_abs_uint2x4(uint2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint3x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint3x1 test_abs_uint3x1(uint3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint3x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint3x2 test_abs_uint3x2(uint3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint3x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint3x3 test_abs_uint3x3(uint3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint3x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint3x4 test_abs_uint3x4(uint3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint4x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint4x1 test_abs_uint4x1(uint4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint4x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint4x2 test_abs_uint4x2(uint4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint4x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint4x3 test_abs_uint4x3(uint4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_uint4x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint4x4 test_abs_uint4x4(uint4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long1x2
+// CHECK: call <2 x i64> @llvm.abs.v2i64(<2 x i64> %{{.*}}, i1 false)
+int64_t1x2 test_abs_long1x2(int64_t1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long1x3
+// CHECK: call <3 x i64> @llvm.abs.v3i64(<3 x i64> %{{.*}}, i1 false)
+int64_t1x3 test_abs_long1x3(int64_t1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long1x4
+// CHECK: call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false)
+int64_t1x4 test_abs_long1x4(int64_t1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long2x1
+// CHECK: call <2 x i64> @llvm.abs.v2i64(<2 x i64> %{{.*}}, i1 false)
+int64_t2x1 test_abs_long2x1(int64_t2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long2x2
+// CHECK: call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false)
+int64_t2x2 test_abs_long2x2(int64_t2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long2x3
+// CHECK: call <6 x i64> @llvm.abs.v6i64(<6 x i64> %{{.*}}, i1 false)
+int64_t2x3 test_abs_long2x3(int64_t2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long2x4
+// CHECK: call <8 x i64> @llvm.abs.v8i64(<8 x i64> %{{.*}}, i1 false)
+int64_t2x4 test_abs_long2x4(int64_t2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long3x1
+// CHECK: call <3 x i64> @llvm.abs.v3i64(<3 x i64> %{{.*}}, i1 false)
+int64_t3x1 test_abs_long3x1(int64_t3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long3x2
+// CHECK: call <6 x i64> @llvm.abs.v6i64(<6 x i64> %{{.*}}, i1 false)
+int64_t3x2 test_abs_long3x2(int64_t3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long3x3
+// CHECK: call <9 x i64> @llvm.abs.v9i64(<9 x i64> %{{.*}}, i1 false)
+int64_t3x3 test_abs_long3x3(int64_t3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long3x4
+// CHECK: call <12 x i64> @llvm.abs.v12i64(<12 x i64> %{{.*}}, i1 false)
+int64_t3x4 test_abs_long3x4(int64_t3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long4x1
+// CHECK: call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false)
+int64_t4x1 test_abs_long4x1(int64_t4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long4x2
+// CHECK: call <8 x i64> @llvm.abs.v8i64(<8 x i64> %{{.*}}, i1 false)
+int64_t4x2 test_abs_long4x2(int64_t4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long4x3
+// CHECK: call <12 x i64> @llvm.abs.v12i64(<12 x i64> %{{.*}}, i1 false)
+int64_t4x3 test_abs_long4x3(int64_t4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_long4x4
+// CHECK: call <16 x i64> @llvm.abs.v16i64(<16 x i64> %{{.*}}, i1 false)
+int64_t4x4 test_abs_long4x4(int64_t4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong1x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t1x2 test_abs_ulong1x2(uint64_t1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong1x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t1x3 test_abs_ulong1x3(uint64_t1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong1x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t1x4 test_abs_ulong1x4(uint64_t1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong2x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t2x1 test_abs_ulong2x1(uint64_t2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong2x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t2x2 test_abs_ulong2x2(uint64_t2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong2x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t2x3 test_abs_ulong2x3(uint64_t2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong2x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t2x4 test_abs_ulong2x4(uint64_t2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong3x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t3x1 test_abs_ulong3x1(uint64_t3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong3x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t3x2 test_abs_ulong3x2(uint64_t3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong3x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t3x3 test_abs_ulong3x3(uint64_t3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong3x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t3x4 test_abs_ulong3x4(uint64_t3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong4x1
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t4x1 test_abs_ulong4x1(uint64_t4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong4x2
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t4x2 test_abs_ulong4x2(uint64_t4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong4x3
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t4x3 test_abs_ulong4x3(uint64_t4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_ulong4x4
+// CHECK: call {{.*}} @{{.*}}hlsl3abs
+uint64_t4x4 test_abs_ulong4x4(uint64_t4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half1x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.fabs.v2f16(<2 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
+half1x2 test_abs_half1x2(half1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half1x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.fabs.v3f16(<3 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
+half1x3 test_abs_half1x3(half1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half1x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.fabs.v4f16(<4 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+half1x4 test_abs_half1x4(half1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half2x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.fabs.v2f16(<2 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
+half2x1 test_abs_half2x1(half2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half2x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.fabs.v4f16(<4 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+half2x2 test_abs_half2x2(half2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half2x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <6 x half> @llvm.fabs.v6f16(<6 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.fabs.v6f32(<6 x float> %{{.*}})
+half2x3 test_abs_half2x3(half2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half2x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <8 x half> @llvm.fabs.v8f16(<8 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.fabs.v8f32(<8 x float> %{{.*}})
+half2x4 test_abs_half2x4(half2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half3x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.fabs.v3f16(<3 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
+half3x1 test_abs_half3x1(half3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half3x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <6 x half> @llvm.fabs.v6f16(<6 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.fabs.v6f32(<6 x float> %{{.*}})
+half3x2 test_abs_half3x2(half3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half3x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <9 x half> @llvm.fabs.v9f16(<9 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <9 x float> @llvm.fabs.v9f32(<9 x float> %{{.*}})
+half3x3 test_abs_half3x3(half3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half3x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <12 x half> @llvm.fabs.v12f16(<12 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.fabs.v12f32(<12 x float> %{{.*}})
+half3x4 test_abs_half3x4(half3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half4x1
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.fabs.v4f16(<4 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+half4x1 test_abs_half4x1(half4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half4x2
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <8 x half> @llvm.fabs.v8f16(<8 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.fabs.v8f32(<8 x float> %{{.*}})
+half4x2 test_abs_half4x2(half4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half4x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <12 x half> @llvm.fabs.v12f16(<12 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.fabs.v12f32(<12 x float> %{{.*}})
+half4x3 test_abs_half4x3(half4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_half4x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <16 x half> @llvm.fabs.v16f16(<16 x half> %{{.*}})
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.fabs.v16f32(<16 x float> %{{.*}})
+half4x4 test_abs_half4x4(half4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float1x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
+float1x2 test_abs_float1x2(float1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float1x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
+float1x3 test_abs_float1x3(float1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float1x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+float1x4 test_abs_float1x4(float1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float2x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
+float2x1 test_abs_float2x1(float2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float2x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+float2x2 test_abs_float2x2(float2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float2x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.fabs.v6f32(<6 x float> %{{.*}})
+float2x3 test_abs_float2x3(float2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float2x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.fabs.v8f32(<8 x float> %{{.*}})
+float2x4 test_abs_float2x4(float2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float3x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
+float3x1 test_abs_float3x1(float3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float3x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.fabs.v6f32(<6 x float> %{{.*}})
+float3x2 test_abs_float3x2(float3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float3x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <9 x float> @llvm.fabs.v9f32(<9 x float> %{{.*}})
+float3x3 test_abs_float3x3(float3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float3x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.fabs.v12f32(<12 x float> %{{.*}})
+float3x4 test_abs_float3x4(float3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float4x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+float4x1 test_abs_float4x1(float4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float4x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <8 x float> @llvm.fabs.v8f32(<8 x float> %{{.*}})
+float4x2 test_abs_float4x2(float4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float4x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <12 x float> @llvm.fabs.v12f32(<12 x float> %{{.*}})
+float4x3 test_abs_float4x3(float4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_float4x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.fabs.v16f32(<16 x float> %{{.*}})
+float4x4 test_abs_float4x4(float4x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double1x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+double1x2 test_abs_double1x2(double1x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double1x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.fabs.v3f64(<3 x double> %{{.*}})
+double1x3 test_abs_double1x3(double1x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double1x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.fabs.v4f64(<4 x double> %{{.*}})
+double1x4 test_abs_double1x4(double1x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double2x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+double2x1 test_abs_double2x1(double2x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double2x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.fabs.v4f64(<4 x double> %{{.*}})
+double2x2 test_abs_double2x2(double2x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double2x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <6 x double> @llvm.fabs.v6f64(<6 x double> %{{.*}})
+double2x3 test_abs_double2x3(double2x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double2x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <8 x double> @llvm.fabs.v8f64(<8 x double> %{{.*}})
+double2x4 test_abs_double2x4(double2x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double3x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.fabs.v3f64(<3 x double> %{{.*}})
+double3x1 test_abs_double3x1(double3x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double3x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <6 x double> @llvm.fabs.v6f64(<6 x double> %{{.*}})
+double3x2 test_abs_double3x2(double3x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double3x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <9 x double> @llvm.fabs.v9f64(<9 x double> %{{.*}})
+double3x3 test_abs_double3x3(double3x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double3x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <12 x double> @llvm.fabs.v12f64(<12 x double> %{{.*}})
+double3x4 test_abs_double3x4(double3x4 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double4x1
+// CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.fabs.v4f64(<4 x double> %{{.*}})
+double4x1 test_abs_double4x1(double4x1 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double4x2
+// CHECK: call reassoc nnan ninf nsz arcp afn <8 x double> @llvm.fabs.v8f64(<8 x double> %{{.*}})
+double4x2 test_abs_double4x2(double4x2 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double4x3
+// CHECK: call reassoc nnan ninf nsz arcp afn <12 x double> @llvm.fabs.v12f64(<12 x double> %{{.*}})
+double4x3 test_abs_double4x3(double4x3 p0) { return abs(p0); }
+
+// CHECK-LABEL: test_abs_double4x4
+// CHECK: call reassoc nnan ninf nsz arcp afn <16 x double> @llvm.fabs.v16f64(<16 x double> %{{.*}})
+double4x4 test_abs_double4x4(double4x4 p0) { return abs(p0); }
diff --git a/clang/test/SemaHLSL/BuiltIns/abs_mat-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/abs_mat-errors.hlsl
new file mode 100644
index 0000000000000..3b496d5558f7c
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/abs_mat-errors.hlsl
@@ -0,0 +1,22 @@
+// 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
+
+float2x2 test_too_few_arg() {
+ return __builtin_elementwise_abs();
+ // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+float2x2 test_too_many_arg(float2x2 p0) {
+ return __builtin_elementwise_abs(p0, p0);
+ // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+float2x2 test_bool_matrix(bool2x2 p0) {
+ return __builtin_elementwise_abs(p0);
+ // expected-error at -1 {{1st argument must be a scalar or vector of signed integer or floating-point types (was 'bool2x2' (aka 'matrix<bool, 2, 2>'))}}
+}
+
+// The raw builtin rejects unsigned matrices.
+float2x2 test_unsigned_matrix(uint2x2 p0) {
+ return __builtin_elementwise_abs(p0);
+ // expected-error at -1 {{1st argument must be a scalar or vector of signed integer or floating-point types (was 'uint2x2' (aka 'matrix<uint, 2, 2>'))}}
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index 87f75529d1290..4acd1dcd1c33e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -193,6 +193,7 @@ static SPIRVTypeInst deduceTypeFromUses(Register Reg, MachineFunction &MF,
case TargetOpcode::G_FPOW:
case TargetOpcode::G_FMINNUM:
case TargetOpcode::G_FMAXNUM:
+ case TargetOpcode::G_FABS:
case TargetOpcode::G_FSQRT:
case TargetOpcode::COPY:
case TargetOpcode::G_STRICT_FMA:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/abs_mat.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/abs_mat.ll
new file mode 100644
index 0000000000000..46234ca1fb597
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/abs_mat.ll
@@ -0,0 +1,115 @@
+; 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 --target-env vulkan1.3 %}
+
+; CHECK-NOT: OpCapability Vector16
+; CHECK-DAG: OpCapability Float16
+; CHECK-DAG: OpCapability Int16
+; CHECK-DAG: %[[#ext:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#void:]] = OpTypeVoid
+; CHECK-DAG: %[[#f32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4f32:]] = OpTypeVector %[[#f32]] 4
+; CHECK-DAG: %[[#vec2f32:]] = OpTypeVector %[[#f32]] 2
+; CHECK-DAG: %[[#f16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4f16:]] = OpTypeVector %[[#f16]] 4
+; CHECK-DAG: %[[#i32:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#vec4i32:]] = OpTypeVector %[[#i32]] 4
+; CHECK-DAG: %[[#vec2i32:]] = OpTypeVector %[[#i32]] 2
+; CHECK-DAG: %[[#i16:]] = OpTypeInt 16 0
+; CHECK-DAG: %[[#vec4i16:]] = OpTypeVector %[[#i16]] 4
+
+ at shuffle_f32_4 = internal addrspace(10) global <4 x float> zeroinitializer
+ at wide_f32_6 = internal addrspace(10) global [6 x float] zeroinitializer
+ at wide_f16_9 = internal addrspace(10) global [9 x half] zeroinitializer
+ at wide_f32_16 = internal addrspace(10) global [16 x float] zeroinitializer
+ at shuffle_i32_4 = internal addrspace(10) global <4 x i32> zeroinitializer
+ at wide_i32_6 = internal addrspace(10) global [6 x i32] zeroinitializer
+ at wide_i16_9 = internal addrspace(10) global [9 x i16] zeroinitializer
+ at wide_i32_16 = internal addrspace(10) global [16 x i32] zeroinitializer
+
+define internal void @abs_float6_from_shuffle() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK: OpExtInst %[[#vec4f32]] %[[#ext]] FAbs
+ ; CHECK: OpExtInst %[[#vec2f32]] %[[#ext]] FAbs
+ %vec = load <4 x float>, ptr addrspace(10) @shuffle_f32_4
+ %va = shufflevector <4 x float> %vec, <4 x float> %vec,
+ <6 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5>
+ %r = call <6 x float> @llvm.fabs.v6f32(<6 x float> %va)
+ store <6 x float> %r, ptr addrspace(10) @wide_f32_6
+ ret void
+}
+
+define internal void @abs_half9() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK-COUNT-2: OpExtInst %[[#vec4f16]] %[[#ext]] FAbs
+ ; CHECK: OpExtInst %[[#f16]] %[[#ext]] FAbs
+ %va = load <9 x half>, ptr addrspace(10) @wide_f16_9
+ %r = call <9 x half> @llvm.fabs.v9f16(<9 x half> %va)
+ store <9 x half> %r, ptr addrspace(10) @wide_f16_9
+ ret void
+}
+
+define internal void @abs_float16() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK-COUNT-4: OpExtInst %[[#vec4f32]] %[[#ext]] FAbs
+ %va = load <16 x float>, ptr addrspace(10) @wide_f32_16
+ %r = call <16 x float> @llvm.fabs.v16f32(<16 x float> %va)
+ store <16 x float> %r, ptr addrspace(10) @wide_f32_16
+ ret void
+}
+
+define internal void @abs_int6_from_shuffle() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK: OpExtInst %[[#vec4i32]] %[[#ext]] SAbs
+ ; CHECK: OpExtInst %[[#vec2i32]] %[[#ext]] SAbs
+ %vec = load <4 x i32>, ptr addrspace(10) @shuffle_i32_4
+ %va = shufflevector <4 x i32> %vec, <4 x i32> %vec,
+ <6 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5>
+ %r = call <6 x i32> @llvm.abs.v6i32(<6 x i32> %va, i1 false)
+ store <6 x i32> %r, ptr addrspace(10) @wide_i32_6
+ ret void
+}
+
+define internal void @abs_short9() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK-COUNT-2: OpExtInst %[[#vec4i16]] %[[#ext]] SAbs
+ ; CHECK: OpExtInst %[[#i16]] %[[#ext]] SAbs
+ %va = load <9 x i16>, ptr addrspace(10) @wide_i16_9
+ %r = call <9 x i16> @llvm.abs.v9i16(<9 x i16> %va, i1 false)
+ store <9 x i16> %r, ptr addrspace(10) @wide_i16_9
+ ret void
+}
+
+define internal void @abs_int16() {
+entry:
+ ; CHECK: OpFunction %[[#void]] None
+ ; CHECK-COUNT-4: OpExtInst %[[#vec4i32]] %[[#ext]] SAbs
+ %va = load <16 x i32>, ptr addrspace(10) @wide_i32_16
+ %r = call <16 x i32> @llvm.abs.v16i32(<16 x i32> %va, i1 false)
+ store <16 x i32> %r, ptr addrspace(10) @wide_i32_16
+ ret void
+}
+
+define void @main() #0 {
+entry:
+ call void @abs_float6_from_shuffle()
+ call void @abs_half9()
+ call void @abs_float16()
+ call void @abs_int6_from_shuffle()
+ call void @abs_short9()
+ call void @abs_int16()
+ ret void
+}
+
+declare <6 x float> @llvm.fabs.v6f32(<6 x float>)
+declare <9 x half> @llvm.fabs.v9f16(<9 x half>)
+declare <16 x float> @llvm.fabs.v16f32(<16 x float>)
+declare <6 x i32> @llvm.abs.v6i32(<6 x i32>, i1)
+declare <9 x i16> @llvm.abs.v9i16(<9 x i16>, i1)
+declare <16 x i32> @llvm.abs.v16i32(<16 x i32>, i1)
+
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
More information about the cfe-commits
mailing list