[clang] 3817ca7 - [SveEmitter] Add IsAppendSVALL and builtins for svptrue and svcnt[bhwd]

Sander de Smalen via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 26 04:45:58 PDT 2020


Author: Sander de Smalen
Date: 2020-04-26T12:44:26+01:00
New Revision: 3817ca7dbf8d360fd6a2ff44722af1405722ad38

URL: https://github.com/llvm/llvm-project/commit/3817ca7dbf8d360fd6a2ff44722af1405722ad38
DIFF: https://github.com/llvm/llvm-project/commit/3817ca7dbf8d360fd6a2ff44722af1405722ad38.diff

LOG: [SveEmitter] Add IsAppendSVALL and builtins for svptrue and svcnt[bhwd]

Some ACLE builtins leave out the argument to specify the predicate
pattern, which is expected to be expanded to an SV_ALL pattern.

This patch adds the flag IsAppendSVALL to append SV_ALL as the final
operand.

Reviewers: SjoerdMeijer, efriedma, rovka, rengolin

Reviewed By: efriedma

Tags: #clang

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

Added: 
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c

Modified: 
    clang/include/clang/Basic/TargetBuiltins.h
    clang/include/clang/Basic/arm_sve.td
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index 1c193ea64a28..8d25dedfef7f 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -240,6 +240,7 @@ namespace clang {
     bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
     bool isPrefetch() const { return Flags & IsPrefetch; }
     bool isReverseCompare() const { return Flags & ReverseCompare; }
+    bool isAppendSVALL() const { return Flags & IsAppendSVALL; }
 
     uint64_t getBits() const { return Flags; }
     bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }

diff  --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index 9387f1d711f0..af6c971000f4 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -181,6 +181,7 @@ def IsOverloadWhileRW         : FlagType<0x00400000>; // Use {pred(default type)
 def IsOverloadCvt             : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
 def OverloadKindMask          : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
 def IsByteIndexed             : FlagType<0x01000000>;
+def IsAppendSVALL             : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
 def IsPrefetch                : FlagType<0x08000000>; // Contiguous prefetches.
 def ReverseCompare            : FlagType<0x20000000>; // Compare operands must be swapped.
 
@@ -837,6 +838,8 @@ def SVQDECH_U : SInst<"svqdech_pat[_{d}]",   "ddIi", "Us", MergeNone, "aarch64_s
 
 def SVPFALSE : SInst<"svpfalse[_b]", "P", "", MergeNone, "", [IsOverloadNone]>;
 
+def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue">;
+def SVPTRUE     : SInst<"svptrue_{d}",     "P",  "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL]>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Counting elements
@@ -845,6 +848,11 @@ def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [I
 def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone]>;
 def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone]>;
 def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone]>;
+
+def SVCNTB : SInst<"svcntb", "n", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone]>;
+def SVCNTH : SInst<"svcnth", "n", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone]>;
+def SVCNTW : SInst<"svcntw", "n", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone]>;
+def SVCNTD : SInst<"svcntd", "n", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone]>;
 ////////////////////////////////////////////////////////////////////////////////
 // Integer arithmetic
 def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]",  "ddqqi",  "il",   MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 18ad1664aa56..58965efd5c44 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -7908,6 +7908,11 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
     if (TypeFlags.getMergeType() == SVETypeFlags::MergeAnyExp)
       InsertExplicitUndefOperand(Builder, Ty, Ops);
 
+    // Some ACLE builtins leave out the argument to specify the predicate
+    // pattern, which is expected to be expanded to an SV_ALL pattern.
+    if (TypeFlags.isAppendSVALL())
+      Ops.push_back(Builder.getInt32(/*SV_ALL*/ 31));
+
     // Predicates must match the main datatype.
     for (unsigned i = 0, e = Ops.size(); i != e; ++i)
       if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType()))

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c
index b8ca5f475f13..377d73471b2c 100644
--- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c
@@ -2,6 +2,14 @@
 
 #include <arm_sve.h>
 
+uint64_t test_svcntb()
+{
+  // CHECK-LABEL: test_svcntb
+  // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.cntb(i32 31)
+  // CHECK: ret i64 %[[INTRINSIC]]
+  return svcntb();
+}
+
 uint64_t test_svcntb_pat()
 {
   // CHECK-LABEL: test_svcntb_pat

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c
index f01036703405..ed5db2e907c9 100644
--- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c
@@ -2,6 +2,14 @@
 
 #include <arm_sve.h>
 
+uint64_t test_svcntd()
+{
+  // CHECK-LABEL: test_svcntd
+  // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.cntd(i32 31)
+  // CHECK: ret i64 %[[INTRINSIC]]
+  return svcntd();
+}
+
 uint64_t test_svcntd_pat()
 {
   // CHECK-LABEL: test_svcntd_pat

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c
index 652970a5f8c4..c8a1e9e9ae39 100644
--- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c
@@ -2,6 +2,14 @@
 
 #include <arm_sve.h>
 
+uint64_t test_svcnth()
+{
+  // CHECK-LABEL: test_svcnth
+  // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.cnth(i32 31)
+  // CHECK: ret i64 %[[INTRINSIC]]
+  return svcnth();
+}
+
 uint64_t test_svcnth_pat()
 {
   // CHECK-LABEL: test_svcnth_pat

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c
index be03d50b891f..604481432ca4 100644
--- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c
@@ -2,6 +2,14 @@
 
 #include <arm_sve.h>
 
+uint64_t test_svcntw()
+{
+  // CHECK-LABEL: test_svcntw
+  // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.cntw(i32 31)
+  // CHECK: ret i64 %[[INTRINSIC]]
+  return svcntw();
+}
+
 uint64_t test_svcntw_pat()
 {
   // CHECK-LABEL: test_svcntw_pat

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c
new file mode 100644
index 000000000000..f5a9ee8ec282
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_sve.h>
+
+svbool_t test_svptrue_b8()
+{
+  // CHECK-LABEL: test_svptrue_b8
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_b8();
+}
+
+svbool_t test_svptrue_b16()
+{
+  // CHECK-LABEL: test_svptrue_b16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_b16();
+}
+
+svbool_t test_svptrue_b32()
+{
+  // CHECK-LABEL: test_svptrue_b32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_b32();
+}
+
+svbool_t test_svptrue_b64()
+{
+  // CHECK-LABEL: test_svptrue_b64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv2i1(<vscale x 2 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_b64();
+}
+
+svbool_t test_svptrue_pat_b8()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 0)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_POW2);
+}
+
+svbool_t test_svptrue_pat_b8_1()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_1
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 1)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL1);
+}
+
+svbool_t test_svptrue_pat_b8_2()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_2
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 2)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL2);
+}
+
+svbool_t test_svptrue_pat_b8_3()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_3
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 3)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL3);
+}
+
+svbool_t test_svptrue_pat_b8_4()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_4
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 4)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL4);
+}
+
+svbool_t test_svptrue_pat_b8_5()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_5
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 5)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL5);
+}
+
+svbool_t test_svptrue_pat_b8_6()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_6
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 6)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL6);
+}
+
+svbool_t test_svptrue_pat_b8_7()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_7
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 7)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL7);
+}
+
+svbool_t test_svptrue_pat_b8_8()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_8
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 8)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL8);
+}
+
+svbool_t test_svptrue_pat_b8_9()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_9
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 9)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL16);
+}
+
+svbool_t test_svptrue_pat_b8_10()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_10
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 10)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL32);
+}
+
+svbool_t test_svptrue_pat_b8_11()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_11
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 11)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL64);
+}
+
+svbool_t test_svptrue_pat_b8_12()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_12
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 12)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL128);
+}
+
+svbool_t test_svptrue_pat_b8_13()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_13
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 13)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_VL256);
+}
+
+svbool_t test_svptrue_pat_b8_14()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_14
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 29)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_MUL4);
+}
+
+svbool_t test_svptrue_pat_b8_15()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_15
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 30)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_MUL3);
+}
+
+svbool_t test_svptrue_pat_b8_16()
+{
+  // CHECK-LABEL: test_svptrue_pat_b8_16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
+  // CHECK: ret <vscale x 16 x i1> %[[INTRINSIC]]
+  return svptrue_pat_b8(SV_ALL);
+}
+
+svbool_t test_svptrue_pat_b16()
+{
+  // CHECK-LABEL: test_svptrue_pat_b16
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 0)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_pat_b16(SV_POW2);
+}
+
+svbool_t test_svptrue_pat_b32()
+{
+  // CHECK-LABEL: test_svptrue_pat_b32
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 1)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_pat_b32(SV_VL1);
+}
+
+svbool_t test_svptrue_pat_b64()
+{
+  // CHECK-LABEL: test_svptrue_pat_b64
+  // CHECK: %[[INTRINSIC:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 2)
+  // CHECK: %[[CAST:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv2i1(<vscale x 2 x i1> %[[INTRINSIC]])
+  // CHECK: ret <vscale x 16 x i1> %[[CAST]]
+  return svptrue_pat_b64(SV_VL2);
+}


        


More information about the cfe-commits mailing list