[clang] 4cad975 - [SveEmitter] Add builtins for svmovlb and svmovlt

Sander de Smalen via cfe-commits cfe-commits at lists.llvm.org
Mon May 11 01:44:08 PDT 2020


Author: Sander de Smalen
Date: 2020-05-11T09:41:58+01:00
New Revision: 4cad97595f40f7a5bda25f4aa107cbbce05bd394

URL: https://github.com/llvm/llvm-project/commit/4cad97595f40f7a5bda25f4aa107cbbce05bd394
DIFF: https://github.com/llvm/llvm-project/commit/4cad97595f40f7a5bda25f4aa107cbbce05bd394.diff

LOG: [SveEmitter] Add builtins for svmovlb and svmovlt

These builtins are expanded in CGBuiltin to use intrinsics
for (signed/unsigned) shift left long top/bottom.

Reviewers: efriedma, SjoerdMeijer

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D79579

Added: 
    clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c
    clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c

Modified: 
    clang/include/clang/Basic/arm_sve.td
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CodeGenFunction.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index 97668dfa162d..b827601d56c1 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -1481,6 +1481,11 @@ def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_
 def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil",    MergeNone, "aarch64_sve_sshllt", [], [ImmCheck<1, ImmCheckShiftLeft,  0>]>;
 def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [], [ImmCheck<1, ImmCheckShiftLeft,  0>]>;
 
+def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh",  "sil",    MergeNone>;
+def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh",  "UsUiUl", MergeNone>;
+def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh",  "sil",    MergeNone>;
+def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh",  "UsUiUl", MergeNone>;
+
 def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]",   "ddhhi", "il",   MergeNone, "aarch64_sve_smlalb_lane",   [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
 def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]",   "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane",   [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
 def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]",   "ddhhi", "il",   MergeNone, "aarch64_sve_smlalt_lane",   [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index dbe8826454dc..c64fde719445 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -7824,6 +7824,13 @@ Value *CodeGenFunction::EmitSVEPMull(SVETypeFlags TypeFlags,
   return EmitSVEReinterpret(Call, Ty);
 }
 
+Value *CodeGenFunction::EmitSVEMovl(SVETypeFlags TypeFlags,
+                                    ArrayRef<Value *> Ops, unsigned BuiltinID) {
+  llvm::Type *OverloadedTy = getSVEType(TypeFlags);
+  Function *F = CGM.getIntrinsic(BuiltinID, OverloadedTy);
+  return Builder.CreateCall(F, {Ops[0], Builder.getInt32(0)});
+}
+
 Value *CodeGenFunction::EmitSVEPrefetchLoad(SVETypeFlags TypeFlags,
                                             SmallVectorImpl<Value *> &Ops,
                                             unsigned BuiltinID) {
@@ -8070,6 +8077,26 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(F, {Ops[0], Ops[1], Ops[0]});
   }
 
+  case SVE::BI__builtin_sve_svmovlb_u16:
+  case SVE::BI__builtin_sve_svmovlb_u32:
+  case SVE::BI__builtin_sve_svmovlb_u64:
+    return EmitSVEMovl(TypeFlags, Ops, Intrinsic::aarch64_sve_ushllb);
+
+  case SVE::BI__builtin_sve_svmovlb_s16:
+  case SVE::BI__builtin_sve_svmovlb_s32:
+  case SVE::BI__builtin_sve_svmovlb_s64:
+    return EmitSVEMovl(TypeFlags, Ops, Intrinsic::aarch64_sve_sshllb);
+
+  case SVE::BI__builtin_sve_svmovlt_u16:
+  case SVE::BI__builtin_sve_svmovlt_u32:
+  case SVE::BI__builtin_sve_svmovlt_u64:
+    return EmitSVEMovl(TypeFlags, Ops, Intrinsic::aarch64_sve_ushllt);
+
+  case SVE::BI__builtin_sve_svmovlt_s16:
+  case SVE::BI__builtin_sve_svmovlt_s32:
+  case SVE::BI__builtin_sve_svmovlt_s64:
+    return EmitSVEMovl(TypeFlags, Ops, Intrinsic::aarch64_sve_sshllt);
+
   case SVE::BI__builtin_sve_svpmullt_u16:
   case SVE::BI__builtin_sve_svpmullt_u64:
   case SVE::BI__builtin_sve_svpmullt_n_u16:

diff  --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 06898f3232f4..61b51118212c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3924,6 +3924,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   llvm::Value *EmitSVEPMull(SVETypeFlags TypeFlags,
                             llvm::SmallVectorImpl<llvm::Value *> &Ops,
                             unsigned BuiltinID);
+  llvm::Value *EmitSVEMovl(SVETypeFlags TypeFlags,
+                           llvm::ArrayRef<llvm::Value *> Ops,
+                           unsigned BuiltinID);
   llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred,
                                     llvm::ScalableVectorType *VTy);
   llvm::Value *EmitSVEGatherLoad(SVETypeFlags TypeFlags,

diff  --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c
new file mode 100644
index 000000000000..ba0d80deaf8a
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+svint16_t test_svmovlb_s16(svint8_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_s16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i16> @llvm.aarch64.sve.sshllb.nxv8i16(<vscale x 16 x i8> %op1, i32 0)
+  // CHECK: ret <vscale x 8 x i16> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_s16'}}
+  return SVE_ACLE_FUNC(svmovlb,_s16,,)(op1);
+}
+
+svint32_t test_svmovlb_s32(svint16_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_s32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.sshllb.nxv4i32(<vscale x 8 x i16> %op1, i32 0)
+  // CHECK: ret <vscale x 4 x i32> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_s32'}}
+  return SVE_ACLE_FUNC(svmovlb,_s32,,)(op1);
+}
+
+svint64_t test_svmovlb_s64(svint32_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_s64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i64> @llvm.aarch64.sve.sshllb.nxv2i64(<vscale x 4 x i32> %op1, i32 0)
+  // CHECK: ret <vscale x 2 x i64> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_s64'}}
+  return SVE_ACLE_FUNC(svmovlb,_s64,,)(op1);
+}
+
+svuint16_t test_svmovlb_u16(svuint8_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_u16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i16> @llvm.aarch64.sve.ushllb.nxv8i16(<vscale x 16 x i8> %op1, i32 0)
+  // CHECK: ret <vscale x 8 x i16> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_u16'}}
+  return SVE_ACLE_FUNC(svmovlb,_u16,,)(op1);
+}
+
+svuint32_t test_svmovlb_u32(svuint16_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_u32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.ushllb.nxv4i32(<vscale x 8 x i16> %op1, i32 0)
+  // CHECK: ret <vscale x 4 x i32> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_u32'}}
+  return SVE_ACLE_FUNC(svmovlb,_u32,,)(op1);
+}
+
+svuint64_t test_svmovlb_u64(svuint32_t op1)
+{
+  // CHECK-LABEL: test_svmovlb_u64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i64> @llvm.aarch64.sve.ushllb.nxv2i64(<vscale x 4 x i32> %op1, i32 0)
+  // CHECK: ret <vscale x 2 x i64> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlb'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlb_u64'}}
+  return SVE_ACLE_FUNC(svmovlb,_u64,,)(op1);
+}

diff  --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c
new file mode 100644
index 000000000000..71a3ea179a91
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+svint16_t test_svmovlt_s16(svint8_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_s16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i16> @llvm.aarch64.sve.sshllt.nxv8i16(<vscale x 16 x i8> %op1, i32 0)
+  // CHECK: ret <vscale x 8 x i16> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_s16'}}
+  return SVE_ACLE_FUNC(svmovlt,_s16,,)(op1);
+}
+
+svint32_t test_svmovlt_s32(svint16_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_s32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.sshllt.nxv4i32(<vscale x 8 x i16> %op1, i32 0)
+  // CHECK: ret <vscale x 4 x i32> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_s32'}}
+  return SVE_ACLE_FUNC(svmovlt,_s32,,)(op1);
+}
+
+svint64_t test_svmovlt_s64(svint32_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_s64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i64> @llvm.aarch64.sve.sshllt.nxv2i64(<vscale x 4 x i32> %op1, i32 0)
+  // CHECK: ret <vscale x 2 x i64> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_s64'}}
+  return SVE_ACLE_FUNC(svmovlt,_s64,,)(op1);
+}
+
+svuint16_t test_svmovlt_u16(svuint8_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_u16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i16> @llvm.aarch64.sve.ushllt.nxv8i16(<vscale x 16 x i8> %op1, i32 0)
+  // CHECK: ret <vscale x 8 x i16> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_u16'}}
+  return SVE_ACLE_FUNC(svmovlt,_u16,,)(op1);
+}
+
+svuint32_t test_svmovlt_u32(svuint16_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_u32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.ushllt.nxv4i32(<vscale x 8 x i16> %op1, i32 0)
+  // CHECK: ret <vscale x 4 x i32> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_u32'}}
+  return SVE_ACLE_FUNC(svmovlt,_u32,,)(op1);
+}
+
+svuint64_t test_svmovlt_u64(svuint32_t op1)
+{
+  // CHECK-LABEL: test_svmovlt_u64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i64> @llvm.aarch64.sve.ushllt.nxv2i64(<vscale x 4 x i32> %op1, i32 0)
+  // CHECK: ret <vscale x 2 x i64> %[[INTRINSIC]]
+  // overload-warning at +2 {{implicit declaration of function 'svmovlt'}}
+  // expected-warning at +1 {{implicit declaration of function 'svmovlt_u64'}}
+  return SVE_ACLE_FUNC(svmovlt,_u64,,)(op1);
+}


        


More information about the cfe-commits mailing list