diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 8aa6e368b901c..5d7b8d839fa84 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -1390,6 +1390,8 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr( break; case NEON::BI__builtin_neon_vabdd_f64: case NEON::BI__builtin_neon_vabds_f32: + case NEON::BI__builtin_neon_vshld_s64: + case NEON::BI__builtin_neon_vshld_u64: return emitNeonCall(cgf.cgm, cgf.getBuilder(), {cgf.convertType(expr->getArg(0)->getType())}, ops, llvmIntrName, cgf.convertType(expr->getType()), loc); @@ -2785,8 +2787,18 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vrshrd_n_s64: case NEON::BI__builtin_neon_vrsrad_n_u64: case NEON::BI__builtin_neon_vrsrad_n_s64: + cgm.errorNYI(expr->getSourceRange(), + std::string("unimplemented AArch64 builtin call: ") + + getContext().BuiltinInfo.getName(builtinID)); + return mlir::Value{}; case NEON::BI__builtin_neon_vshld_n_s64: - case NEON::BI__builtin_neon_vshld_n_u64: + case NEON::BI__builtin_neon_vshld_n_u64: { + auto loc = getLoc(expr->getExprLoc()); + std::optional amt = + expr->getArg(1)->getIntegerConstantExpr(getContext()); + assert(amt && "Expected argument to be a constant"); + return builder.createShiftLeft(loc, ops[0], amt->getZExtValue()); + } case NEON::BI__builtin_neon_vshrd_n_s64: case NEON::BI__builtin_neon_vshrd_n_u64: case NEON::BI__builtin_neon_vsrad_n_s64: diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c b/clang/test/CodeGen/AArch64/neon-intrinsics.c index bfaea2b8ae909..8eb6cd86339d6 100644 --- a/clang/test/CodeGen/AArch64/neon-intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c @@ -12052,26 +12052,6 @@ uint64_t test_vqsubd_u64(uint64_t a, uint64_t b) { return vqsubd_u64(a, b); } -// CHECK-LABEL: define dso_local i64 @test_vshld_s64( -// CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[VSHLD_S64_I:%.*]] = call i64 @llvm.aarch64.neon.sshl.i64(i64 [[A]], i64 [[B]]) -// CHECK-NEXT: ret i64 [[VSHLD_S64_I]] -// -int64_t test_vshld_s64(int64_t a, int64_t b) { - return vshld_s64(a, b); -} - -// CHECK-LABEL: define dso_local i64 @test_vshld_u64( -// CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[VSHLD_U64_I:%.*]] = call i64 @llvm.aarch64.neon.ushl.i64(i64 [[A]], i64 [[B]]) -// CHECK-NEXT: ret i64 [[VSHLD_U64_I]] -// -uint64_t test_vshld_u64(uint64_t a, int64_t b) { - return vshld_u64(a, b); -} - // CHECK-LABEL: define dso_local i8 @test_vqshlb_s8( // CHECK-SAME: i8 noundef [[A:%.*]], i8 noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -17887,16 +17867,6 @@ uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) { return vrsra_n_u64(a, b, 1); } -// CHECK-LABEL: define dso_local i64 @test_vshld_n_s64( -// CHECK-SAME: i64 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[SHLD_N:%.*]] = shl i64 [[A]], 1 -// CHECK-NEXT: ret i64 [[SHLD_N]] -// -int64_t test_vshld_n_s64(int64_t a) { - return (int64_t)vshld_n_s64(a, 1); -} - // CHECK-LABEL: define dso_local <1 x i64> @test_vshl_n_s64( // CHECK-SAME: <1 x i64> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -17909,16 +17879,6 @@ int64x1_t test_vshl_n_s64(int64x1_t a) { return vshl_n_s64(a, 1); } -// CHECK-LABEL: define dso_local i64 @test_vshld_n_u64( -// CHECK-SAME: i64 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[SHLD_N:%.*]] = shl i64 [[A]], 63 -// CHECK-NEXT: ret i64 [[SHLD_N]] -// -uint64_t test_vshld_n_u64(uint64_t a) { - return (uint64_t)vshld_n_u64(a, 63); -} - // CHECK-LABEL: define dso_local <1 x i64> @test_vshl_n_u64( // CHECK-SAME: <1 x i64> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] diff --git a/clang/test/CodeGen/AArch64/neon/intrinsics.c b/clang/test/CodeGen/AArch64/neon/intrinsics.c index aad0fbe12c389..bf8e62feda8da 100644 --- a/clang/test/CodeGen/AArch64/neon/intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon/intrinsics.c @@ -1,8 +1,8 @@ // REQUIRES: aarch64-registered-target || arm-registered-target -// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=LLVM -// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=LLVM %} -// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-cir -o - %s | FileCheck %s --check-prefixes=CIR %} +// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=ALL,LLVM +// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=ALL,LLVM %} +// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-cir -o - %s | FileCheck %s --check-prefixes=ALL,CIR %} //============================================================================= // NOTES @@ -936,3 +936,49 @@ uint32x4_t test_vabaq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) { // LLVM-NEXT: ret <4 x i32> [[ADD_I]] return vabaq_u32(v1, v2, v3); } +//===------------------------------------------------------===// +// 2.1.3.1.1. Vector Shift Left +//===------------------------------------------------------===// + +// ALL-LABEL: test_vshld_n_s64 +int64_t test_vshld_n_s64(int64_t a) { + // CIR: cir.shift(left, {{.*}}) + + // LLVM-SAME: i64 {{.*}} [[A:%.*]]) + // LLVM: [[SHL_N:%.*]] = shl i64 [[A]], 1 + // LLVM: ret i64 [[SHL_N]] + return (int64_t)vshld_n_s64(a, 1); +} + +// ALL-LABEL: test_vshld_n_u64 +int64_t test_vshld_n_u64(int64_t a) { + // CIR: cir.shift(left, {{.*}}) + + // LLVM-SAME: i64 {{.*}} [[A:%.*]]) + // LLVM: [[SHL_N:%.*]] = shl i64 [[A]], 1 + // LLVM: ret i64 [[SHL_N]] + return (int64_t)vshld_n_u64(a, 1); +} + +// LLVM-LABEL: test_vshld_s64 +// CIR-LABEL: vshld_s64 +int64_t test_vshld_s64(int64_t a,int64_t b) { + // CIR: cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!s64i, !s64i) -> !s64i + + // LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) #[[ATTR0:[0-9]+]] { + // LLVM: [[VSHLD_S64_I:%.*]] = call i64 @llvm.aarch64.neon.sshl.i64(i64 [[A]], i64 [[B]]) + // LLVM: ret i64 [[VSHLD_S64_I]] + return (int64_t)vshld_s64(a, b); +} + +// LLVM-LABEL: test_vshld_u64 +// CIR-LABEL: vshld_u64 +int64_t test_vshld_u64(int64_t a,int64_t b) { + // CIR: cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!u64i, !s64i) -> !u64i + + // LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) #[[ATTR0:[0-9]+]] { + // LLVM: [[VSHLD_S64_I:%.*]] = call i64 @llvm.aarch64.neon.ushl.i64(i64 [[A]], i64 [[B]]) + // LLVM: ret i64 [[VSHLD_S64_I]] + return (int64_t)vshld_u64(a, b); +} +