Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9202,6 +9202,10 @@ "argument should be an 8-bit value shifted by a multiple of 8 bits">; def err_argument_not_shifted_byte_or_xxff : Error< "argument should be an 8-bit value shifted by a multiple of 8 bits, or in the form 0x??FF">; +def err_rotation_argument_to_cadd + : Error<"argument should be the value 90 or 270">; +def err_rotation_argument_to_cmla + : Error<"argument should be the value 0,90,180 or 270">; def warn_neon_vector_initializer_non_portable : Warning< "vector initializers are not compatible with NEON intrinsics in big endian " "mode">, InGroup>; Index: clang/include/clang/Basic/arm_sve.td =================================================================== --- clang/include/clang/Basic/arm_sve.td +++ clang/include/clang/Basic/arm_sve.td @@ -62,7 +62,10 @@ // d: default // c: const pointer type // P: predicate type +// e: 1/2 width unsigned elements, 2x element count // h: 1/2 width elements, 2x element count +// q: 1/4 width elements, 4x element count +// o: 4x width elements, 1/4 element count // // i: constant uint64_t // @@ -159,6 +162,11 @@ def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2 def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1) def ImmCheck0_7 : ImmCheckType<6>; // 0..7 +def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1) +def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1) +def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1) +def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270] +def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0,90,180,270] class ImmCheck { int Arg = arg; @@ -306,7 +314,19 @@ // Floating-point arithmetic def SVTMAD : SInst<"svtmad[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_ftmad_x", [], [ImmCheck<2, ImmCheck0_7>]>; +def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, + ImmCheck<4, ImmCheckComplexRotAll90>]>; + +def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; + //////////////////////////////////////////////////////////////////////////////// // Saturating scalar arithmetic def SVQDECH_S : SInst<"svqdech_pat[_{d}]", "ddIi", "s", MergeNone, "aarch64_sve_sqdech", [], [ImmCheck<2, ImmCheck1_16>]>; def SVQDECH_U : SInst<"svqdech_pat[_{d}]", "ddIi", "Us", MergeNone, "aarch64_sve_uqdech", [], [ImmCheck<2, ImmCheck1_16>]>; + +//////////////////////////////////////////////////////////////////////////////// +// Integer arithmetic +def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -2011,6 +2011,27 @@ int ArgNum, CheckTy, ElementSizeInBits; std::tie(ArgNum, CheckTy, ElementSizeInBits) = I; + typedef bool(*OptionSetCheckFnTy)(int64_t Value); + + // Function that checks whether the operand (ArgNum) is an immediate + // that is one of the predefined values. + auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm, + int ErrDiag) -> bool { + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + llvm::APSInt Imm; + if (SemaBuiltinConstantArg(TheCall, ArgNum, Imm)) + return true; + + if (!CheckImm(Imm.getSExtValue())) + return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); + return false; + }; + switch ((SVETypeFlags::ImmCheckType)CheckTy) { case SVETypeFlags::ImmCheckPredicatePattern: if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) @@ -2043,6 +2064,34 @@ ElementSizeInBits - 1)) HasError = true; break; + case SVETypeFlags::ImmCheckLaneIndex: + if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (1 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckLaneIndexCompRotate: + if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (2 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckLaneIndexDot: + if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (4 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckComplexRot90_270: + if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; }, + diag::err_rotation_argument_to_cadd)) + HasError = true; + break; + case SVETypeFlags::ImmCheckComplexRotAll90: + if (CheckImmediateInSet( + [](int64_t V) { + return V == 0 || V == 90 || V == 180 || V == 270; + }, + diag::err_rotation_argument_to_cmla)) + HasError = true; + break; } } Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svfloat16_t test_svcmla_f16_m_0(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_f16_m(pg, op1, op2, op3, 0); +} + +svfloat16_t test_svcmla_f16_m_90(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_f16_m(pg, op1, op2, op3, 90); +} + +svfloat16_t test_svcmla_f16_m_180(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_f16_m(pg, op1, op2, op3, 180); +} + +svfloat16_t test_svcmla_f16_m_270(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_f16_m(pg, op1, op2, op3, 270); +} + +svfloat32_t test_svcmla_f32_m_0(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_f32_m(pg, op1, op2, op3, 0); +} + +svfloat32_t test_svcmla_f32_m_90(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_f32_m(pg, op1, op2, op3, 90); +} + +svfloat32_t test_svcmla_f32_m_180(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_f32_m(pg, op1, op2, op3, 180); +} + +svfloat32_t test_svcmla_f32_m_270(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_f32_m(pg, op1, op2, op3, 270); +} + +svfloat64_t test_svcmla_f64_m_0(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_f64_m(pg, op1, op2, op3, 0); +} + +svfloat64_t test_svcmla_f64_m_90(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_f64_m(pg, op1, op2, op3, 90); +} + +svfloat64_t test_svcmla_f64_m_180(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_f64_m(pg, op1, op2, op3, 180); +} + +svfloat64_t test_svcmla_f64_m_270(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_f64_m(pg, op1, op2, op3, 270); +} + + +// LANE + +svfloat16_t test_svcmla_lane_f16_0_0(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_0_0 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 0, i32 0) + // CHECK: ret + return svcmla_lane_f16(op1, op2, op3, 0, 0); +} + +svfloat16_t test_svcmla_lane_f16_3_90(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_90 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 90) + // CHECK: ret + return svcmla_lane_f16(op1, op2, op3, 3, 90); +} + +svfloat16_t test_svcmla_lane_f16_3_180(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_180 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 180) + // CHECK: ret + return svcmla_lane_f16(op1, op2, op3, 3, 180); +} + +svfloat16_t test_svcmla_lane_f16_3_270(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_270 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 270) + // CHECK: ret + return svcmla_lane_f16(op1, op2, op3, 3, 270); +} + +svfloat32_t test_svcmla_lane_f32_0_0(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_0_0 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 0, i32 0) + // CHECK: ret + return svcmla_lane_f32(op1, op2, op3, 0, 0); +} + +svfloat32_t test_svcmla_lane_f32_1_90(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_90 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 90) + // CHECK: ret + return svcmla_lane_f32(op1, op2, op3, 1, 90); +} + +svfloat32_t test_svcmla_lane_f32_1_180(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_180 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 180) + // CHECK: ret + return svcmla_lane_f32(op1, op2, op3, 1, 180); +} + +svfloat32_t test_svcmla_lane_f32_1_270(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_270 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 270) + // CHECK: ret + return svcmla_lane_f32(op1, op2, op3, 1, 270); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla_shortform.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla_shortform.c @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svfloat16_t test_svcmla_f16_m_0(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 0); +} + +svfloat16_t test_svcmla_f16_m_90(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 90); +} + +svfloat16_t test_svcmla_f16_m_180(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 180); +} + +svfloat16_t test_svcmla_f16_m_270(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_f16_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv8f16( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 270); +} + +svfloat32_t test_svcmla_f32_m_0(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 0); +} + +svfloat32_t test_svcmla_f32_m_90(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 90); +} + +svfloat32_t test_svcmla_f32_m_180(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 180); +} + +svfloat32_t test_svcmla_f32_m_270(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_f32_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv4f32( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 270); +} + +svfloat64_t test_svcmla_f64_m_0(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_0 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 0) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 0); +} + +svfloat64_t test_svcmla_f64_m_90(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_90 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 90) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 90); +} + +svfloat64_t test_svcmla_f64_m_180(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_180 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 180) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 180); +} + +svfloat64_t test_svcmla_f64_m_270(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svcmla_f64_m_270 + // CHECK: %[[P0:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.nxv2f64( %[[P0]], %op1, %op2, %op3, i32 270) + // CHECK: ret + return svcmla_m(pg, op1, op2, op3, 270); +} + + +// LANE + +svfloat16_t test_svcmla_lane_f16_0_0(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_0_0 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 0, i32 0) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 0, 0); +} + +svfloat16_t test_svcmla_lane_f16_3_90(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_90 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 90) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 3, 90); +} + +svfloat16_t test_svcmla_lane_f16_3_180(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_180 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 180) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 3, 180); +} + +svfloat16_t test_svcmla_lane_f16_3_270(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f16_3_270 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv8f16( %op1, %op2, %op3, i32 3, i32 270) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 3, 270); +} + +svfloat32_t test_svcmla_lane_f32_0_0(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_0_0 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 0, i32 0) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 0, 0); +} + +svfloat32_t test_svcmla_lane_f32_1_90(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_90 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 90) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 1, 90); +} + +svfloat32_t test_svcmla_lane_f32_1_180(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_180 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 180) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 1, 180); +} + +svfloat32_t test_svcmla_lane_f32_1_270(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svcmla_lane_f32_1_270 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcmla.lane.nxv4f32( %op1, %op2, %op3, i32 1, i32 270) + // CHECK: ret + return svcmla_lane(op1, op2, op3, 1, 270); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svint32_t test_svdot_lane_s32(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane_s32(op1, op2, op3, 0); +} + +svint32_t test_svdot_lane_s32_1(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane_s32(op1, op2, op3, 1); +} + +svint32_t test_svdot_lane_s32_2(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_2 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 2) + // CHECK: ret + return svdot_lane_s32(op1, op2, op3, 2); +} + +svint32_t test_svdot_lane_s32_3(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svdot_lane_s32(op1, op2, op3, 3); +} + +svuint32_t test_svdot_lane_u32(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane_u32(op1, op2, op3, 0); +} + +svuint32_t test_svdot_lane_u32_1(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane_u32(op1, op2, op3, 1); +} + +svuint32_t test_svdot_lane_u32_2(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_2 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 2) + // CHECK: ret + return svdot_lane_u32(op1, op2, op3, 2); +} + +svuint32_t test_svdot_lane_u32_3(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svdot_lane_u32(op1, op2, op3, 3); +} + +svint64_t test_svdot_lane_s64(svint64_t op1, svint16_t op2, svint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv2i64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane_s64(op1, op2, op3, 0); +} + +svint64_t test_svdot_lane_s64_1(svint64_t op1, svint16_t op2, svint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv2i64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane_s64(op1, op2, op3, 1); +} + +svuint64_t test_svdot_lane_u64(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv2i64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane_u64(op1, op2, op3, 0); +} + +svuint64_t test_svdot_lane_u64_1(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv2i64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane_u64(op1, op2, op3, 1); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot_shortform.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot_shortform.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svint32_t test_svdot_lane_s32(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane(op1, op2, op3, 0); +} + +svint32_t test_svdot_lane_s32_1(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane(op1, op2, op3, 1); +} + +svint32_t test_svdot_lane_s32_2(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_2 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 2) + // CHECK: ret + return svdot_lane(op1, op2, op3, 2); +} + +svint32_t test_svdot_lane_s32_3(svint32_t op1, svint8_t op2, svint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv4i32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svdot_lane(op1, op2, op3, 3); +} + +svuint32_t test_svdot_lane_u32(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane(op1, op2, op3, 0); +} + +svuint32_t test_svdot_lane_u32_1(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane(op1, op2, op3, 1); +} + +svuint32_t test_svdot_lane_u32_2(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_2 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 2) + // CHECK: ret + return svdot_lane(op1, op2, op3, 2); +} + +svuint32_t test_svdot_lane_u32_3(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv4i32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svdot_lane(op1, op2, op3, 3); +} + +svint64_t test_svdot_lane_s64(svint64_t op1, svint16_t op2, svint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv2i64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane(op1, op2, op3, 0); +} + +svint64_t test_svdot_lane_s64_1(svint64_t op1, svint16_t op2, svint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_s64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sdot.lane.nxv2i64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane(op1, op2, op3, 1); +} + +svuint64_t test_svdot_lane_u64(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv2i64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svdot_lane(op1, op2, op3, 0); +} + +svuint64_t test_svdot_lane_u64_1(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + // CHECK-LABEL: test_svdot_lane_u64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.udot.lane.nxv2i64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svdot_lane(op1, op2, op3, 1); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svfloat16_t test_svmla_lane_f16(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv8f16( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane_f16(op1, op2, op3, 0); +} + +svfloat16_t test_svmla_lane_f16_7(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f16_7 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv8f16( %op1, %op2, %op3, i32 7) + // CHECK: ret + return svmla_lane_f16(op1, op2, op3, 7); +} + +svfloat32_t test_svmla_lane_f32(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv4f32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane_f32(op1, op2, op3, 0); +} + +svfloat32_t test_svmla_lane_f32_3(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv4f32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svmla_lane_f32(op1, op2, op3, 3); +} + +svfloat64_t test_svmla_lane_f64(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv2f64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane_f64(op1, op2, op3, 0); +} + +svfloat64_t test_svmla_lane_f64_1(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv2f64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svmla_lane_f64(op1, op2, op3, 1); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla_shortform.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla_shortform.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svfloat16_t test_svmla_lane_f16(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv8f16( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane(op1, op2, op3, 0); +} + +svfloat16_t test_svmla_lane_f16_7(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f16_7 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv8f16( %op1, %op2, %op3, i32 7) + // CHECK: ret + return svmla_lane(op1, op2, op3, 7); +} + +svfloat32_t test_svmla_lane_f32(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f32 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv4f32( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane(op1, op2, op3, 0); +} + +svfloat32_t test_svmla_lane_f32_3(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f32_3 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv4f32( %op1, %op2, %op3, i32 3) + // CHECK: ret + return svmla_lane(op1, op2, op3, 3); +} + +svfloat64_t test_svmla_lane_f64(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f64 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv2f64( %op1, %op2, %op3, i32 0) + // CHECK: ret + return svmla_lane(op1, op2, op3, 0); +} + +svfloat64_t test_svmla_lane_f64_1(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + // CHECK-LABEL: test_svmla_lane_f64_1 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fmla.lane.nxv2f64( %op1, %op2, %op3, i32 1) + // CHECK: ret + return svmla_lane(op1, op2, op3, 1); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech_shortform.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech_shortform.c @@ -0,0 +1,155 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -D__ARM_FEATURE_SVE %s | FileCheck %s + +#include + +svint16_t test_svqdech_pat_s16(svint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_s16 + // CHECK: @llvm.aarch64.sve.sqdech.nxv8i16( %op, i32 0, i32 1) + // CHECK: ret + return svqdech_pat(op, SV_POW2, 1); +} + +svint16_t test_svqdech_pat_s16_all(svint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_s16_all + // CHECK: @llvm.aarch64.sve.sqdech.nxv8i16( %op, i32 31, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_ALL, 16); +} + +svuint16_t test_svqdech_pat_u16_pow2(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_pow2 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 0, i32 1) + // CHECK: ret + return svqdech_pat(op, SV_POW2, 1); +} + +svuint16_t test_svqdech_pat_u16_vl1(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl1 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 1, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL1, 16); +} + +svuint16_t test_svqdech_pat_u16_vl2(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl2 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 2, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL2, 16); +} + +svuint16_t test_svqdech_pat_u16_vl3(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl3 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 3, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL3, 16); +} + +svuint16_t test_svqdech_pat_u16_vl4(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl4 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 4, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL4, 16); +} + +svuint16_t test_svqdech_pat_u16_vl5(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl5 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 5, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL5, 16); +} + +svuint16_t test_svqdech_pat_u16_vl6(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl6 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 6, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL6, 16); +} + +svuint16_t test_svqdech_pat_u16_vl7(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl7 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 7, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL7, 16); +} + +svuint16_t test_svqdech_pat_u16_vl8(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl8 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 8, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL8, 16); +} + +svuint16_t test_svqdech_pat_u16_vl16(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl16 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 9, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL16, 16); +} + +svuint16_t test_svqdech_pat_u16_vl32(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl32 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 10, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL32, 16); +} + +svuint16_t test_svqdech_pat_u16_vl64(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl64 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 11, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL64, 16); +} + +svuint16_t test_svqdech_pat_u16_vl128(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl128 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 12, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL128, 16); +} + +svuint16_t test_svqdech_pat_u16_vl256(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_vl256 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 13, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_VL256, 16); +} + +svuint16_t test_svqdech_pat_u16_mul4(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_mul4 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 29, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_MUL4, 16); +} + +svuint16_t test_svqdech_pat_u16_mul3(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_mul3 + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 30, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_MUL3, 16); +} + +svuint16_t test_svqdech_pat_u16_all(svuint16_t op) +{ + // CHECK-LABEL: test_svqdech_pat_u16_all + // CHECK: @llvm.aarch64.sve.uqdech.nxv8i16( %op, i32 31, i32 16) + // CHECK: ret + return svqdech_pat(op, SV_ALL, 16); +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + +#include +// +// cmla +// + +svfloat16_t test_svcmla_f16_m_1(svbool_t pg, svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + return svcmla_f16_m(pg, op1, op2, op3, 1); // expected-error {{argument should be the value 0,90,180 or 270}} +} + +svfloat32_t test_svcmla_f32_m_1(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + return svcmla_f32_m(pg, op1, op2, op3, 1); // expected-error {{argument should be the value 0,90,180 or 270}} +} + + +// LANE + +svfloat16_t test_svcmla_lane_f16_neg1(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + return svcmla_lane_f16(op1, op2, op3, -1, 0); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}} +} + +svfloat16_t test_svcmla_lane_f16_4(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + return svcmla_lane_f16(op1, op2, op3, 4, 0); // expected-error {{argument value 4 is outside the valid range [0, 3]}} +} + +svfloat32_t test_svcmla_lane_f32_neg1(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + return svcmla_lane_f32(op1, op2, op3, -1, 0); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}} +} + +svfloat32_t test_svcmla_lane_f32_1(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + return svcmla_lane_f32(op1, op2, op3, 2, 0); // expected-error {{argument value 2 is outside the valid range [0, 1]}} +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + +#include +// +// dot +// + +svint32_t test_svdot_lane_s32(svint32_t op1, svint8_t op2, svint8_t op3) +{ + return svdot_lane_s32(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svint32_t test_svdot_lane_s32_2(svint32_t op1, svint8_t op2, svint8_t op3) +{ + return svdot_lane_s32(op1, op2, op3, 4); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svint64_t test_svdot_lane_s64(svint64_t op1, svint16_t op2, svint16_t op3) +{ + return svdot_lane_s64(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} + +svint64_t test_svdot_lane_s64_2(svint64_t op1, svint16_t op2, svint16_t op3) +{ + return svdot_lane_s64(op1, op2, op3, 2); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} + +svuint32_t test_svdot_lane_u32(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + return svdot_lane_u32(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svuint32_t test_svdot_lane_u32_2(svuint32_t op1, svuint8_t op2, svuint8_t op3) +{ + return svdot_lane_u32(op1, op2, op3, 4); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svuint64_t test_svdot_lane_u64(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + return svdot_lane_u64(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} + +svuint64_t test_svdot_lane_u64_2(svuint64_t op1, svuint16_t op2, svuint16_t op3) +{ + return svdot_lane_u64(op1, op2, op3, 2); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} Index: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + +#include +// +// mla +// + +svfloat16_t test_svmla_lane_f16(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + return svmla_lane_f16(op1, op2, op3, 8); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} +} + +svfloat16_t test_svmla_lane(svfloat16_t op1, svfloat16_t op2, svfloat16_t op3) +{ + return svmla_lane(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 7]}} +} + +svfloat32_t test_svmla_lane_f32(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + return svmla_lane_f32(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svfloat32_t test_svmla_lane_1(svfloat32_t op1, svfloat32_t op2, svfloat32_t op3) +{ + return svmla_lane(op1, op2, op3, 4); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 3]}} +} + +svfloat64_t test_svmla_lane_f64(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + return svmla_lane_f64(op1, op2, op3, 2); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} + +svfloat64_t test_svmla_lane_2(svfloat64_t op1, svfloat64_t op2, svfloat64_t op3) +{ + return svmla_lane(op1, op2, op3, -1); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [0, 1]}} +} Index: clang/utils/TableGen/SveEmitter.cpp =================================================================== --- clang/utils/TableGen/SveEmitter.cpp +++ clang/utils/TableGen/SveEmitter.cpp @@ -471,9 +471,19 @@ Bitwidth = ElementBitwidth; NumVectors = 0; break; + case 'e': + Signed = false; + ElementBitwidth /= 2; + break; case 'h': ElementBitwidth /= 2; break; + case 'q': + ElementBitwidth /= 4; + break; + case 'o': + ElementBitwidth *= 4; + break; case 'P': Signed = true; Float = false;