[clang] [CIR][AArch64] Upstream addition-across-vector (incl. widening) NEON builtins (PR #193396)

Vicky Nguyen via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 28 22:21:57 PDT 2026


================
@@ -2719,6 +2732,32 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr,
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
     return mlir::Value{};
+  case NEON::BI__builtin_neon_vaddlv_u8:
+  case NEON::BI__builtin_neon_vaddlvq_u8:
+  case NEON::BI__builtin_neon_vaddlv_u16:
+  case NEON::BI__builtin_neon_vaddlvq_u16:
+  case NEON::BI__builtin_neon_vaddlv_s8:
+  case NEON::BI__builtin_neon_vaddlvq_s8:
+  case NEON::BI__builtin_neon_vaddlv_s16:
+  case NEON::BI__builtin_neon_vaddlvq_s16: {
+    mlir::Type argTy = convertType(expr->getArg(0)->getType());
+    mlir::Type userRetTy = convertType(expr->getType());
+    auto eltTy = mlir::cast<cir::IntType>(
+        mlir::cast<cir::VectorType>(argTy).getElementType());
+    bool isUnsigned = !eltTy.isSigned();
----------------
iamvickynguyen wrote:

It's because `vaddlv_*` has the last argument with `VectorType`, so `usgn` will always be signed (`arg->getIntegerConstantExpr()` is false [CIRGenBuiltinAArch64.cpp#L2167](https://github.com/llvm/llvm-project/blob/main/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp#L2167))

Just a note from what I found :grinning:  , [NeonEmitter.cpp#L1107](https://github.com/llvm/llvm-project/blob/main/clang/utils/TableGen/NeonEmitter.cpp#L1107) adds an extra integer to the last argument if an intrinsic is `ClassB`. Since `vaddlv_*` returns a scalar, it isn't `ClassB`, so no extra integer last argument.

https://github.com/llvm/llvm-project/pull/193396


More information about the cfe-commits mailing list