Author: Andrzej Warzyński
Date: 2025-12-17T14:37:53Z
New Revision: 7149e05b7f010e6b1387106a0327545cf3fa9e4b

URL: 
https://github.com/llvm/llvm-project/commit/7149e05b7f010e6b1387106a0327545cf3fa9e4b
DIFF: 
https://github.com/llvm/llvm-project/commit/7149e05b7f010e6b1387106a0327545cf3fa9e4b.diff

LOG: [CIR][AArch64] Add lowering for `svlen` builtins (#172346)

This patch adds lowering support for integer `svlen` builtins.

Because `svlen` builtins take scalable vector types (e.g. `svuint64_t`) as
arguments, this change also extends `cir::VectorType` to represent scalable
vectors. Since `cir::VectorType` is ultimately lowered to MLIR’s builtin
`VectorType`, the implementation follows the same approach: scalability is
modeled using an additional boolean member (`isScalable`, defaulting to
`false`).

Further work will be needed to fully support scalable vectors in CIR:
* `cir::VectorType::getTypeSizeInBits` currently returns the compile-time base
  vector size. Its meaning for scalable vectors is unclear and may require
  redesign.
* The assembly format for `cir::VectorType` will require a custom parser and
  printer to encode scalability (and agreement on the concrete syntax). This is
  not required for this patch.

References:
* 
https://arm-software.github.io/acle/main/acle.html#markdown-toc-sve-vector-types

---------

Co-authored-by: Andy Kaylor <[email protected]>

Added: 
    clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c

Modified: 
    clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
    clang/include/clang/CIR/Dialect/IR/CIRTypes.td
    clang/lib/CIR/CodeGen/CIRGenBuilder.h
    clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
    clang/lib/CIR/CodeGen/CIRGenTypes.cpp
    clang/lib/CIR/Dialect/IR/CIRTypes.cpp
    clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
    clang/test/CIR/IR/invalid-vector.cir

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index bfe48e4f286fd..899a475bc4ac8 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -597,7 +597,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     IntType integralTy =
         getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType()));
     VectorType integralVecTy =
-        VectorType::get(context, integralTy, vecCast.getSize());
+        cir::VectorType::get(integralTy, vecCast.getSize());
     return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs);
   }
 

diff  --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 59b97f0c6d39a..ce64bef3270ed 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -422,8 +422,9 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [
 ]> {
   let summary = "CIR vector type";
   let description = [{
-    The `!cir.vector` type represents a fixed-size, one-dimensional vector.
-    It takes two parameters: the element type and the number of elements.
+    The `!cir.vector` type represents a one-dimensional vector.
+    It takes three parameters: the element type, the number of elements and the
+    scalability flag (optional, defaults to `false`).
 
     Syntax:
 
@@ -444,19 +445,21 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [
   }];
 
   let parameters = (ins
-    CIR_VectorElementType:$elementType,
-    "uint64_t":$size
+    CIR_VectorElementType:$element_type,
+    "uint64_t":$size,
+    OptionalParameter<"bool">:$is_scalable
   );
 
   let assemblyFormat = [{
-    `<` $size `x` $elementType `>`
+    `<` $size `x` $element_type `>`
   }];
 
   let builders = [
     TypeBuilderWithInferredContext<(ins
-      "mlir::Type":$elementType, "uint64_t":$size
+      "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool",
+      "false">:$is_scalable
     ), [{
-        return $_get(elementType.getContext(), elementType, size);
+        return $_get(element_type.getContext(), element_type, size, 
is_scalable);
     }]>,
   ];
 
@@ -467,6 +470,7 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [
   }];
 
   let genVerifyDecl = 1;
+  let skipDefaultBuilders = 1;
 }
 
 
//===----------------------------------------------------------------------===//

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 55f4b42689c8e..e16dfb6b24d7b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -285,6 +285,11 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   cir::IntType getUInt32Ty() { return typeCache.uInt32Ty; }
   cir::IntType getUInt64Ty() { return typeCache.uInt64Ty; }
 
+  cir::FP16Type getFp16Ty() { return typeCache.fP16Ty; }
+  cir::BF16Type getBfloat6Ty() { return typeCache.bFloat16Ty; }
+  cir::SingleType getSingleTy() { return typeCache.floatTy; }
+  cir::DoubleType getDoubleTy() { return typeCache.doubleTy; }
+
   cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal);
 
   cir::ConstantOp getConstInt(mlir::Location loc, llvm::APInt intVal,
@@ -629,8 +634,8 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2,
                    llvm::ArrayRef<mlir::Attribute> maskAttrs) {
     auto vecType = mlir::cast<cir::VectorType>(vec1.getType());
-    auto resultTy = cir::VectorType::get(getContext(), 
vecType.getElementType(),
-                                         maskAttrs.size());
+    auto resultTy =
+        cir::VectorType::get(vecType.getElementType(), maskAttrs.size());
     return cir::VecShuffleOp::create(*this, loc, resultTy, vec1, vec2,
                                      getArrayAttr(maskAttrs));
   }

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 696180458a2f6..e28b3c6cdc2ff 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -11,6 +11,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "CIRGenBuilder.h"
 #include "CIRGenFunction.h"
 #include "clang/CIR/MissingFeatures.h"
 
@@ -30,6 +31,27 @@ using namespace clang;
 using namespace clang::CIRGen;
 using namespace llvm;
 
+template <typename... Operands>
+static mlir::Value emitIntrinsicCallOp(CIRGenBuilderTy &builder,
+                                       mlir::Location loc, const StringRef str,
+                                       const mlir::Type &resTy,
+                                       Operands &&...op) {
+  return cir::LLVMIntrinsicCallOp::create(builder, loc,
+                                          builder.getStringAttr(str), resTy,
+                                          std::forward<Operands>(op)...)
+      .getResult();
+}
+
+// Generate vscale * scalingFactor
+static mlir::Value genVscaleTimesFactor(mlir::Location loc,
+                                        CIRGenBuilderTy builder,
+                                        mlir::Type cirTy,
+                                        int32_t scalingFactor) {
+  mlir::Value vscale = emitIntrinsicCallOp(builder, loc, "vscale", cirTy);
+  return builder.createNUWAMul(loc, vscale,
+                               builder.getUInt64(scalingFactor, loc));
+}
+
 std::optional<mlir::Value>
 CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID,
                                           const CallExpr *expr) {
@@ -43,6 +65,8 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID,
 
   assert(!cir::MissingFeatures::aarch64SVEIntrinsics());
 
+  mlir::Location loc = getLoc(expr->getExprLoc());
+
   switch (builtinID) {
   default:
     return std::nullopt;
@@ -101,18 +125,26 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned 
builtinID,
   case SVE::BI__builtin_sve_svdupq_n_s32:
   case SVE::BI__builtin_sve_svpfalse_b:
   case SVE::BI__builtin_sve_svpfalse_c:
-  case SVE::BI__builtin_sve_svlen_bf16:
-  case SVE::BI__builtin_sve_svlen_f16:
-  case SVE::BI__builtin_sve_svlen_f32:
-  case SVE::BI__builtin_sve_svlen_f64:
-  case SVE::BI__builtin_sve_svlen_s8:
-  case SVE::BI__builtin_sve_svlen_s16:
-  case SVE::BI__builtin_sve_svlen_s32:
-  case SVE::BI__builtin_sve_svlen_s64:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
   case SVE::BI__builtin_sve_svlen_u8:
+  case SVE::BI__builtin_sve_svlen_s8:
+    return genVscaleTimesFactor(loc, builder, convertType(expr->getType()), 
16);
   case SVE::BI__builtin_sve_svlen_u16:
+  case SVE::BI__builtin_sve_svlen_s16:
+  case SVE::BI__builtin_sve_svlen_f16:
+  case SVE::BI__builtin_sve_svlen_bf16:
+    return genVscaleTimesFactor(loc, builder, convertType(expr->getType()), 8);
   case SVE::BI__builtin_sve_svlen_u32:
+  case SVE::BI__builtin_sve_svlen_s32:
+  case SVE::BI__builtin_sve_svlen_f32:
+    return genVscaleTimesFactor(loc, builder, convertType(expr->getType()), 4);
   case SVE::BI__builtin_sve_svlen_u64:
+  case SVE::BI__builtin_sve_svlen_s64:
+  case SVE::BI__builtin_sve_svlen_f64:
+    return genVscaleTimesFactor(loc, builder, convertType(expr->getType()), 2);
   case SVE::BI__builtin_sve_svtbl2_u8:
   case SVE::BI__builtin_sve_svtbl2_s8:
   case SVE::BI__builtin_sve_svtbl2_u16:

diff  --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 7f000ece8a494..2e0193ac71e49 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -7,6 +7,7 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
 
 #include <cassert>
 
@@ -320,6 +321,57 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
           cir::IntType::get(&getMLIRContext(), astContext.getTypeSize(ty),
                             /*isSigned=*/true);
       break;
+
+    // SVE types
+    case BuiltinType::SveInt8:
+      resultType =
+          cir::VectorType::get(builder.getSInt8Ty(), 16, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveUint8:
+      resultType =
+          cir::VectorType::get(builder.getUInt8Ty(), 16, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveInt16:
+      resultType =
+          cir::VectorType::get(builder.getSInt16Ty(), 8, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveUint16:
+      resultType =
+          cir::VectorType::get(builder.getUInt16Ty(), 8, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveFloat16:
+      resultType = cir::VectorType::get(builder.getFp16Ty(), 8,
+                                        /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveBFloat16:
+      resultType = cir::VectorType::get(builder.getFp16Ty(), 8,
+                                        /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveInt32:
+      resultType =
+          cir::VectorType::get(builder.getSInt32Ty(), 4, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveUint32:
+      resultType =
+          cir::VectorType::get(builder.getUInt32Ty(), 4, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveFloat32:
+      resultType = cir::VectorType::get(builder.getSingleTy(), 4,
+                                        /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveInt64:
+      resultType =
+          cir::VectorType::get(builder.getSInt64Ty(), 2, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveUint64:
+      resultType =
+          cir::VectorType::get(builder.getUInt64Ty(), 2, /*is_scalable=*/true);
+      break;
+    case BuiltinType::SveFloat64:
+      resultType = cir::VectorType::get(builder.getDoubleTy(), 2,
+                                        /*is_scalable=*/true);
+      break;
+
     // Unsigned integral types.
     case BuiltinType::Char8:
     case BuiltinType::Char16:

diff  --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp 
b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 9a37a4f4e3996..c7531022fdfb8 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -822,7 +822,7 @@ cir::VectorType::getABIAlignment(const ::mlir::DataLayout 
&dataLayout,
 
 mlir::LogicalResult cir::VectorType::verify(
     llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
-    mlir::Type elementType, uint64_t size) {
+    mlir::Type elementType, uint64_t size, bool scalable) {
   if (size == 0)
     return emitError() << "the number of vector elements must be non-zero";
   return success();

diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7d854997848aa..7c9cf8e2c2e2d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2910,7 +2910,7 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter 
&converter,
   });
   converter.addConversion([&](cir::VectorType type) -> mlir::Type {
     const mlir::Type ty = converter.convertType(type.getElementType());
-    return mlir::VectorType::get(type.getSize(), ty);
+    return mlir::VectorType::get(type.getSize(), ty, {type.getIsScalable()});
   });
   converter.addConversion([&](cir::BoolType type) -> mlir::Type {
     return mlir::IntegerType::get(type.getContext(), 1,

diff  --git a/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c 
b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c
new file mode 100644
index 0000000000000..ac202ef792ff9
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c
@@ -0,0 +1,170 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -disable-O0-optnone 
-Werror -Wall -fclangir -emit-cir -o - %s | FileCheck %s 
--check-prefixes=ALL,CIR
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve 
-disable-O0-optnone -Werror -Wall -fclangir -emit-cir -o - %s | FileCheck %s 
--check-prefixes=ALL,CIR
+
+// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -disable-O0-optnone 
-Werror -Wall -fclangir -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=ALL,LLVM_OGCG_CIR
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve 
-disable-O0-optnone -Werror -Wall -fclangir -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=ALL,LLVM_OGCG_CIR
+
+// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -disable-O0-optnone 
-Werror -Wall -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=ALL,LLVM_OGCG_CIR
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve 
-disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=ALL,LLVM_OGCG_CIR
+
+#include <arm_sve.h>
+
+#if defined __ARM_FEATURE_SME
+#define MODE_ATTR __arm_streaming
+#else
+#define MODE_ATTR
+#endif
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// ALL-LABEL: @test_svlen_u8
+uint64_t test_svlen_u8(svuint8_t op) MODE_ATTR
+{
+// CIR:     %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> !u64i
+// CIR:     %[[C16:.*]] = cir.const #cir.int<16> : !u64i
+// CIR:     %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) nuw : !u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 16
+  return SVE_ACLE_FUNC(svlen,_u8,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_s8(
+uint64_t test_svlen_s8(svint8_t op) MODE_ATTR
+{
+// CIR:     %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> !u64i
+// CIR:     %[[C16:.*]] = cir.const #cir.int<16> : !u64i
+// CIR:     %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) nuw : !u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 16
+  return SVE_ACLE_FUNC(svlen,_s8,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_u16(
+uint64_t test_svlen_u16(svuint16_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C8:.*]] = cir.const #cir.int<8> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 8
+  return SVE_ACLE_FUNC(svlen,_u16,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_s16(
+uint64_t test_svlen_s16(svint16_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C8:.*]] = cir.const #cir.int<8> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 8
+  return SVE_ACLE_FUNC(svlen,_s16,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_f16(
+uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C8:.*]] = cir.const #cir.int<8> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 8
+  return SVE_ACLE_FUNC(svlen,_f16,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_bf16(
+uint64_t test_svlen_bf16(svbfloat16_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C8:.*]] = cir.const #cir.int<8> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 8
+  return SVE_ACLE_FUNC(svlen,_bf16,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_u32(
+uint64_t test_svlen_u32(svuint32_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C4:.*]] = cir.const #cir.int<4> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64  [[VSCALE]], 4
+  return SVE_ACLE_FUNC(svlen,_u32,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_s32(
+uint64_t test_svlen_s32(svint32_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C4:.*]] = cir.const #cir.int<4> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 4
+  return SVE_ACLE_FUNC(svlen,_s32,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_f32(
+uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C4:.*]] = cir.const #cir.int<4> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 4
+  return SVE_ACLE_FUNC(svlen,_f32,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_u64(
+uint64_t test_svlen_u64(svuint64_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C2:.*]] = cir.const #cir.int<2> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64  [[VSCALE]], 2
+  return SVE_ACLE_FUNC(svlen,_u64,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_s64
+uint64_t test_svlen_s64(svint64_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C2:.*]] = cir.const #cir.int<2> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 2
+  return SVE_ACLE_FUNC(svlen,_s64,,)(op);
+}
+
+// ALL-LABEL: @test_svlen_f64
+uint64_t test_svlen_f64(svfloat64_t op) MODE_ATTR
+{
+// CIR:           %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale"  : () -> 
!u64i
+// CIR:           %[[C2:.*]] = cir.const #cir.int<2> : !u64i
+// CIR:           %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) nuw : 
!u64i
+
+// LLVM_OGCG_CIR:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
+// LLVM_OGCG_CIR:    [[RES:%.*]] = mul nuw i64 [[VSCALE]], 2
+  return SVE_ACLE_FUNC(svlen,_f64,,)(op);
+}

diff  --git a/clang/test/CIR/IR/invalid-vector.cir 
b/clang/test/CIR/IR/invalid-vector.cir
index 679994925786e..7b8c89cc58248 100644
--- a/clang/test/CIR/IR/invalid-vector.cir
+++ b/clang/test/CIR/IR/invalid-vector.cir
@@ -4,7 +4,7 @@
 
 module  {
 
-// expected-error @below {{failed to verify 'elementType'}}
+// expected-error @below {{failed to verify 'element_type'}}
 cir.global external @vec_b = #cir.zero : !cir.vector<4 x !cir.array<!s32i x 
10>>
 
 }


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to