Index: clang/include/clang/Basic/TargetBuiltins.h =================================================================== --- clang/include/clang/Basic/TargetBuiltins.h +++ clang/include/clang/Basic/TargetBuiltins.h @@ -234,6 +234,7 @@ bool isZExtReturn() const { return Flags & IsZExtReturn; } bool isNoAuto() const { return Flags & NoAuto; } bool isNotOverloaded() const { return Flags & NoOverloadTy; } + bool isExpandOp1SVALL() const { return Flags & Op1SVALL; } uint64_t getBits() const { return Flags; } bool isFlagSet(uint64_t Flag) const { return Flags & Flag; } Index: clang/include/clang/Basic/arm_sve.td =================================================================== --- clang/include/clang/Basic/arm_sve.td +++ clang/include/clang/Basic/arm_sve.td @@ -168,6 +168,7 @@ def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default def NoAuto : FlagType<0x00100000>; def NoOverloadTy : FlagType<0x00200000>; +def Op1SVALL : FlagType<0x00400000>; // These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h class ImmCheckType { @@ -408,6 +409,9 @@ def SVPFALSE : SInst<"svpfalse[_b]", "P", "", MergeNone, "", [NoOverloadTy]>; +def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue">; +def SVPTRUE : SInst<"svptrue_{d}", "P", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [Op1SVALL]>; + //////////////////////////////////////////////////////////////////////////////// // Integer arithmetic def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -7634,6 +7634,14 @@ if (TypeFlags.getMergeType() == SVETypeFlags::MergeAnyExp) InsertExplicitUndefOperand(Builder, Ty, Ops); + // Insert a `SVAll (31)` for Op1 + if (TypeFlags.isExpandOp1SVALL()) { + if (Ops.size() <= 1) + Ops.push_back(Builder.getInt32(31)); + else + Ops.insert(&Ops[1], Builder.getInt32(31)); + } + // Predicates must match the main datatype. for (unsigned i = 0, e = Ops.size(); i != e; ++i) { if (auto PredTy = dyn_cast(Ops[i]->getType())) Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c =================================================================== --- /dev/null +++ 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 + +svbool_t test_svptrue_b8() +{ + // CHECK-LABEL: test_svptrue_b8 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) + // CHECK: ret %[[INTRINSIC]] + return svptrue_b8(); +} + +svbool_t test_svptrue_b16() +{ + // CHECK-LABEL: test_svptrue_b16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_b16(); +} + +svbool_t test_svptrue_b32() +{ + // CHECK-LABEL: test_svptrue_b32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_b32(); +} + +svbool_t test_svptrue_b64() +{ + // CHECK-LABEL: test_svptrue_b64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_b64(); +} + +svbool_t test_svptrue_pat_b8() +{ + // CHECK-LABEL: test_svptrue_pat_b8 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_POW2); +} + +svbool_t test_svptrue_pat_b8_1() +{ + // CHECK-LABEL: test_svptrue_pat_b8_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 1) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL1); +} + +svbool_t test_svptrue_pat_b8_2() +{ + // CHECK-LABEL: test_svptrue_pat_b8_2 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 2) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL2); +} + +svbool_t test_svptrue_pat_b8_3() +{ + // CHECK-LABEL: test_svptrue_pat_b8_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 3) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL3); +} + +svbool_t test_svptrue_pat_b8_4() +{ + // CHECK-LABEL: test_svptrue_pat_b8_4 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 4) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL4); +} + +svbool_t test_svptrue_pat_b8_5() +{ + // CHECK-LABEL: test_svptrue_pat_b8_5 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 5) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL5); +} + +svbool_t test_svptrue_pat_b8_6() +{ + // CHECK-LABEL: test_svptrue_pat_b8_6 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 6) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL6); +} + +svbool_t test_svptrue_pat_b8_7() +{ + // CHECK-LABEL: test_svptrue_pat_b8_7 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 7) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL7); +} + +svbool_t test_svptrue_pat_b8_8() +{ + // CHECK-LABEL: test_svptrue_pat_b8_8 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 8) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL8); +} + +svbool_t test_svptrue_pat_b8_9() +{ + // CHECK-LABEL: test_svptrue_pat_b8_9 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 9) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL16); +} + +svbool_t test_svptrue_pat_b8_10() +{ + // CHECK-LABEL: test_svptrue_pat_b8_10 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 10) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL32); +} + +svbool_t test_svptrue_pat_b8_11() +{ + // CHECK-LABEL: test_svptrue_pat_b8_11 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 11) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL64); +} + +svbool_t test_svptrue_pat_b8_12() +{ + // CHECK-LABEL: test_svptrue_pat_b8_12 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 12) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL128); +} + +svbool_t test_svptrue_pat_b8_13() +{ + // CHECK-LABEL: test_svptrue_pat_b8_13 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 13) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_VL256); +} + +svbool_t test_svptrue_pat_b8_14() +{ + // CHECK-LABEL: test_svptrue_pat_b8_14 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 29) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_MUL4); +} + +svbool_t test_svptrue_pat_b8_15() +{ + // CHECK-LABEL: test_svptrue_pat_b8_15 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 30) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_MUL3); +} + +svbool_t test_svptrue_pat_b8_16() +{ + // CHECK-LABEL: test_svptrue_pat_b8_16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) + // CHECK: ret %[[INTRINSIC]] + return svptrue_pat_b8(SV_ALL); +} + +svbool_t test_svptrue_pat_b16() +{ + // CHECK-LABEL: test_svptrue_pat_b16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv8i1(i32 0) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_pat_b16(SV_POW2); +} + +svbool_t test_svptrue_pat_b32() +{ + // CHECK-LABEL: test_svptrue_pat_b32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 1) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_pat_b32(SV_VL1); +} + +svbool_t test_svptrue_pat_b64() +{ + // CHECK-LABEL: test_svptrue_pat_b64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ptrue.nxv2i1(i32 2) + // CHECK: %[[CAST:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %[[INTRINSIC]]) + // CHECK: ret %[[CAST]] + return svptrue_pat_b64(SV_VL2); +}