diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index f92b9d1bf373..392dcf7688aa 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -3836,7 +3836,21 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, } case NEON::BI__builtin_neon_vrshrd_n_u64: case NEON::BI__builtin_neon_vrshrd_n_s64: { - llvm_unreachable("NEON::BI__builtin_neon_vrshrd_n_s64 NYI"); + cir::IntType IntType = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 + ? builder.getUInt64Ty() + : builder.getSInt64Ty(); + + const StringRef Intrinsic = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 + ? "aarch64.neon.urshl" + : "aarch64.neon.srshl"; + Ops.push_back(emitScalarExpr(E->getArg(1))); + std::optional APSInt = + E->getArg(1)->getIntegerConstantExpr(getContext()); + assert(APSInt && "Expected argument to be a constant"); + int64_t SV = -APSInt->getSExtValue(); + Ops[1] = builder.getSInt64(SV, getLoc(E->getExprLoc())); + return emitNeonCall(builder, {IntType, builder.getSInt64Ty()}, Ops, + Intrinsic, IntType, getLoc(E->getExprLoc())); } case NEON::BI__builtin_neon_vrsrad_n_u64: case NEON::BI__builtin_neon_vrsrad_n_s64: { diff --git a/clang/test/CIR/CodeGen/AArch64/neon.c b/clang/test/CIR/CodeGen/AArch64/neon.c index c14f2ba0c2d1..405392ff0294 100644 --- a/clang/test/CIR/CodeGen/AArch64/neon.c +++ b/clang/test/CIR/CodeGen/AArch64/neon.c @@ -15209,12 +15209,16 @@ uint64_t test_vshrd_n_u64_3(uint64_t a) { // LLVM: ret i64 [[SHRD_N]] } -// NYI-LABEL: @test_vrshrd_n_s64( -// NYI: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.srshl.i64(i64 %a, i64 -63) -// NYI: ret i64 [[VRSHR_N]] -// int64_t test_vrshrd_n_s64(int64_t a) { -// return (int64_t)vrshrd_n_s64(a, 63); -// } +int64_t test_vrshrd_n_s64(int64_t a) { + return (int64_t)vrshrd_n_s64(a, 63); + + // CIR-LABEL: vrshrd_n_s64 + // CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.srshl" {{.*}}, {{.*}} : (!s64i, !s64i) -> !s64i + + // LLVM-LABEL: @test_vrshrd_n_s64( + // LLVM: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.srshl.i64(i64 %0, i64 -63) + // LLVM: ret i64 [[VRSHR_N]] +} // NYI-LABEL: @test_vrshr_n_s64( // NYI: [[TMP0:%.*]] = bitcast <1 x i64> %a to <8 x i8> @@ -15225,12 +15229,16 @@ uint64_t test_vshrd_n_u64_3(uint64_t a) { // return vrshr_n_s64(a, 1); // } -// NYI-LABEL: @test_vrshrd_n_u64( -// NYI: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.urshl.i64(i64 %a, i64 -63) -// NYI: ret i64 [[VRSHR_N]] -// uint64_t test_vrshrd_n_u64(uint64_t a) { -// return (uint64_t)vrshrd_n_u64(a, 63); -// } +uint64_t test_vrshrd_n_u64(uint64_t a) { + return (uint64_t)vrshrd_n_u64(a, 63); + + // CIR-LABEL: vrshrd_n_u64 + // CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.urshl" {{.*}}, {{.*}} : (!u64i, !s64i) -> !u64i + + // LLVM-LABEL: @test_vrshrd_n_u64( + // LLVM: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.urshl.i64(i64 %0, i64 -63) + // LLVM: ret i64 [[VRSHR_N]] +} // NYI-LABEL: @test_vrshr_n_u64( // NYI: [[TMP0:%.*]] = bitcast <1 x i64> %a to <8 x i8>