diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -547,8 +547,8 @@ def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "..qI", "siQsQi", OP_QRDMULH_LN>; } let ArchGuard = "defined(__aarch64__)" in { -def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..qI", "siQsQi">; -def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..qI", "siQsQi">; +def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">; +def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">; } let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5803,8 +5803,12 @@ case NEON::BI__builtin_neon_vqdmulh_lane_v: case NEON::BI__builtin_neon_vqrdmulhq_lane_v: case NEON::BI__builtin_neon_vqrdmulh_lane_v: { + llvm::Type* RTy = Ty; + if (BuiltinID == NEON::BI__builtin_neon_vqdmulhq_lane_v || + BuiltinID == NEON::BI__builtin_neon_vqrdmulhq_lane_v) + RTy = llvm::VectorType::get(Ty->getVectorElementType(), Ty->getVectorNumElements() * 2); llvm::Type *Tys[2] = { - Ty, GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, + RTy, GetNeonType(this, NeonTypeFlags(Type.getEltType(), false, /*isQuad*/ false))}; return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); } diff --git a/clang/test/CodeGen/arm-neon-range-checks.c b/clang/test/CodeGen/arm-neon-range-checks.c --- a/clang/test/CodeGen/arm-neon-range-checks.c +++ b/clang/test/CodeGen/arm-neon-range-checks.c @@ -280,6 +280,13 @@ vqdmulh_lane_s32(a, b, 1); } +void test_vqdmulhq_lane(int32x4_t a, int32x2_t b) { + vqdmulhq_lane_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} + vqdmulhq_lane_s32(a, b, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + vqdmulhq_lane_s32(a, b, 0); + vqdmulhq_lane_s32(a, b, 1); +} + #if defined(__aarch64__) void test_vqdmulh_laneq(int32x2_t a, int32x4_t b) { vqdmulh_laneq_s32(a, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} @@ -393,6 +400,13 @@ vqrdmulh_lane_s32(a, v, 1); } +void test_vqrdmulhq_lane(int32x4_t a, int32x2_t v) { + vqrdmulhq_lane_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} + vqrdmulhq_lane_s32(a, v, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + vqrdmulhq_lane_s32(a, v, 0); + vqrdmulhq_lane_s32(a, v, 1); +} + #if defined(__aarch64__) void test_vqrdmulh_laneq(int32x2_t a, int32x4_t v) { vqrdmulh_laneq_s32(a, v, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}