diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 5e807a091f7a..25aab790d59f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -4397,9 +4397,6 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, case NEON::BI__builtin_neon_vmul_n_f64: { llvm_unreachable("NEON::BI__builtin_neon_vmul_n_f64 NYI"); } - case NEON::BI__builtin_neon_vaddlv_u8: { - llvm_unreachable("NEON::BI__builtin_neon_vaddlv_u8 NYI"); - } case NEON::BI__builtin_neon_vaddlvq_u8: { llvm_unreachable("NEON::BI__builtin_neon_vaddlvq_u8 NYI"); } @@ -4413,8 +4410,16 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, usgn ? "aarch64.neon.uaddlv" : "aarch64.neon.saddlv", usgn ? UInt32Ty : SInt32Ty, getLoc(E->getExprLoc())); } + case NEON::BI__builtin_neon_vaddlv_u8: + usgn = true; + [[fallthrough]]; case NEON::BI__builtin_neon_vaddlv_s8: { - llvm_unreachable("NEON::BI__builtin_neon_vaddlv_s8 NYI"); + cir::VectorType vTy = cir::VectorType::get(usgn ? UInt8Ty : SInt8Ty, 8); + Ops.push_back(emitScalarExpr(E->getArg(0))); + Ops[0] = emitNeonCall(builder, {vTy}, Ops, + usgn ? "aarch64.neon.uaddlv" : "aarch64.neon.saddlv", + usgn ? UInt32Ty : SInt32Ty, getLoc(E->getExprLoc())); + return builder.createIntCast(Ops[0], usgn ? UInt16Ty : SInt16Ty); } case NEON::BI__builtin_neon_vaddlv_u16: usgn = true; diff --git a/clang/test/CIR/CodeGen/AArch64/neon-arith.c b/clang/test/CIR/CodeGen/AArch64/neon-arith.c index ba2f2cb6958d..657ae11fabbf 100644 --- a/clang/test/CIR/CodeGen/AArch64/neon-arith.c +++ b/clang/test/CIR/CodeGen/AArch64/neon-arith.c @@ -905,6 +905,29 @@ int32_t test_vaddlvq_s16(int16x8_t a) { // LLVM: ret i32 [[VADDLV_I]] } +int16_t test_vaddlv_s8(int8x8_t a) { + return vaddlv_s8(a); + + // CIR-LABEL: vaddlv_s8 + // CIR: cir.llvm.intrinsic "aarch64.neon.saddlv" {{%.*}}: (!cir.vector) -> !s32i + + // LLVM: {{.*}}test_vaddlv_s8(<8 x i8>{{.*}}[[A:%.*]]) + // LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i8(<8 x i8> [[A]]) + // LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16 + // LLVM-NEXT: ret i16 [[TMP0]] +} + +uint16_t test_vaddlv_u8(uint8x8_t a) { + return vaddlv_u8(a); + + // CIR-LABEL: vaddlv_u8 + // CIR: cir.llvm.intrinsic "aarch64.neon.uaddlv" {{%.*}}: (!cir.vector) -> !u32i + + // LLVM: {{.*}}test_vaddlv_u8(<8 x i8>{{.*}}[[A:%.*]]) + // LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i8(<8 x i8> [[A]]) + // LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16 + // LLVM-NEXT: ret i16 [[TMP0]] +} int32_t test_vaddlv_s16(int16x4_t a) { return vaddlv_s16(a);