https://github.com/banach-space updated https://github.com/llvm/llvm-project/pull/172346
From d03aa53225f758305c7aeffc9d0779426f5a9df3 Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Sat, 13 Dec 2025 16:36:20 +0000 Subject: [PATCH 1/9] [CIR][AArch64] Add lowering for `svlen` builtins (1/2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds lowering support for integer `svlen` builtins. Floating-point variants are omitted for now and will be added once FP type helpers (e.g., `getFP32Ty()`) become available. Because svlen builtins take scalable vector types (e.g., `svuint64_t`), this change also extends `cir::VectorType` to represent scalable vectors. Since `cir::VectorType` is ultimately converted to MLIR’s builtin `VectorType` during lowering to LLVM IR, the implementation follows the same approach: scalability is modelled using an additional boolean member (`isScalable`, defaulting to `false`). Further work will be needed to properly support scalable vectors within CIR: * `cir::VectorType::getTypeSizeInBits` currently returns the compile-time base vector size. Its meaning and usefulness for scalable vectors are unclear and may need re-design. * 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 * https://developer.arm.com/documentation/100891/0609/coding-considerations/using-sve-intrinsics-directly-in-your-c-code --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 3 +- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 14 +- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 4 +- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 46 +++++- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 48 ++++++ clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 2 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +- .../CodeGenBuiltins/AArch64/acle_sve_len.c | 143 ++++++++++++++++++ 8 files changed, 243 insertions(+), 19 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index b4b02e24f85cc..8ca07ca3f17b8 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -596,8 +596,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { VectorType vecCast = mlir::cast<VectorType>(lhs.getType()); IntType integralTy = getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType())); - VectorType integralVecTy = - VectorType::get(context, integralTy, vecCast.getSize()); + VectorType integralVecTy = 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..3ca56be4e4a10 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: @@ -445,7 +446,8 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ let parameters = (ins CIR_VectorElementType:$elementType, - "uint64_t":$size + "uint64_t":$size, + OptionalParameter<"bool">:$isScalable ); let assemblyFormat = [{ @@ -454,9 +456,10 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ let builders = [ TypeBuilderWithInferredContext<(ins - "mlir::Type":$elementType, "uint64_t":$size + "mlir::Type":$elementType, "uint64_t":$size, CArg<"bool", + "false">:$isScalable ), [{ - return $_get(elementType.getContext(), elementType, size); + return $_get(elementType.getContext(), elementType, size, isScalable); }]>, ]; @@ -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 5b10bddd054ea..2a15b1f7703be 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -628,8 +628,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..7a9661b727dc7 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,17 @@ 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(); +} + std::optional<mlir::Value> CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, const CallExpr *expr) { @@ -41,6 +53,16 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, return mlir::Value{}; } + mlir::Location loc = getLoc(expr->getExprLoc()); + // Generate vscale * scalingFactor + auto vscaleTimesFactor = [&](int32_t scalingFactor) { + StringRef intrinsicName = "vscale.i64"; + auto vscale = emitIntrinsicCallOp(builder, loc, intrinsicName, + convertType(expr->getType())); + return builder.createMul(loc, vscale, + builder.getUInt64(scalingFactor, loc)); + }; + assert(!cir::MissingFeatures::aarch64SVEIntrinsics()); switch (builtinID) { @@ -101,18 +123,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 vscaleTimesFactor(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 vscaleTimesFactor(8); case SVE::BI__builtin_sve_svlen_u32: + case SVE::BI__builtin_sve_svlen_s32: + case SVE::BI__builtin_sve_svlen_f32: + return vscaleTimesFactor(4); case SVE::BI__builtin_sve_svlen_u64: + case SVE::BI__builtin_sve_svlen_s64: + case SVE::BI__builtin_sve_svlen_f64: + return vscaleTimesFactor(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..3bb075d7581f7 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,53 @@ 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, /*isScalable=*/true); + break; + case BuiltinType::SveUint8: + resultType = + cir::VectorType::get(builder.getUInt8Ty(), 16, /*isScalable=*/true); + break; + case BuiltinType::SveInt16: + resultType = + cir::VectorType::get(builder.getSInt16Ty(), 8, /*isScalable=*/true); + break; + case BuiltinType::SveUint16: + resultType = + cir::VectorType::get(builder.getUInt16Ty(), 8, /*isScalable=*/true); + break; + // TODO: Waiting for FP type helpers + // case BuiltinType::SveFloat16: + // resultType = cir::VectorType::get(builder.getF16Type(), 8, + // /*isScalable=*/true); break; + case BuiltinType::SveInt32: + resultType = + cir::VectorType::get(builder.getSInt32Ty(), 4, /*isScalable=*/true); + break; + case BuiltinType::SveUint32: + resultType = + cir::VectorType::get(builder.getUInt32Ty(), 4, /*isScalable=*/true); + break; + // TODO: Waiting for FP type helpers + // case BuiltinType::SveFloat32: + // resultType = cir::VectorType::get(builder.getF32Type(), 4, + // /*isScalable=*/true); break; + case BuiltinType::SveInt64: + resultType = + cir::VectorType::get(builder.getSInt64Ty(), 2, /*isScalable=*/true); + break; + case BuiltinType::SveUint64: + resultType = + cir::VectorType::get(builder.getUInt64Ty(), 2, /*isScalable=*/true); + break; + // TODO: Waiting for FP type helpers + // case BuiltinType::SveFloat64: + // resultType = cir::VectorType::get(builder.getF64Type(), 2, + // /*isScalable=*/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..3ad2ddef04030 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c @@ -0,0 +1,143 @@ +// 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 +// 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 + +#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.i64" : () -> !u64i +// CIR: %[[C16:.*]] = cir.const #cir.int<16> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul 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.i64" : () -> !u64i +// CIR: %[[C16:.*]] = cir.const #cir.int<16> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul 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.i64" : () -> !u64i +// CIR: %[[C8:.*]] = cir.const #cir.int<8> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul 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.i64" : () -> !u64i +// CIR: %[[C8:.*]] = cir.const #cir.int<8> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 8 + return SVE_ACLE_FUNC(svlen,_s16,,)(op); +} + +// TODO: Waiting for FP type helpers +// uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR +// { +// return SVE_ACLE_FUNC(svlen,_f16,,)(op); +// } + +// TODO: Waiting for FP type helpers +// uint64_t test_svlen_bf16(svbfloat16_t op) MODE_ATTR +// { +// 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.i64" : () -> !u64i +// CIR: %[[C4:.*]] = cir.const #cir.int<4> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul 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.i64" : () -> !u64i +// CIR: %[[C4:.*]] = cir.const #cir.int<4> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 4 + return SVE_ACLE_FUNC(svlen,_s32,,)(op); +} + +// TODO: Waiting for FP type helpers +// uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR +// { +// 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.i64" : () -> !u64i +// CIR: %[[C2:.*]] = cir.const #cir.int<2> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul 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.i64" : () -> !u64i +// CIR: %[[C2:.*]] = cir.const #cir.int<2> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) : !u64i + +// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 2 + return SVE_ACLE_FUNC(svlen,_s64,,)(op); +} + +// TODO: Waiting for FP type helpers +// uint64_t test_svlen_f64(svfloat64_t op) MODE_ATTR +// { +// return SVE_ACLE_FUNC(svlen,_f64,,)(op); +// } From 20ae9b1dd0e51b5e917878f58480fe2034833968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= <[email protected]> Date: Tue, 16 Dec 2025 13:50:10 +0000 Subject: [PATCH 2/9] Update clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h Co-authored-by: Andy Kaylor <[email protected]> --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 8ca07ca3f17b8..696ffa42107e8 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -596,7 +596,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { VectorType vecCast = mlir::cast<VectorType>(lhs.getType()); IntType integralTy = getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType())); - VectorType integralVecTy = VectorType::get(integralTy, vecCast.getSize()); + VectorType integralVecTy = cir::VectorType::get(integralTy, vecCast.getSize()); return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs); } From efb48f0f637a8845a61b813f32c37b334813d216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= <[email protected]> Date: Tue, 16 Dec 2025 13:50:28 +0000 Subject: [PATCH 3/9] Update clang/include/clang/CIR/Dialect/IR/CIRTypes.td Co-authored-by: Andy Kaylor <[email protected]> --- clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 3ca56be4e4a10..8e1f288eab822 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -447,7 +447,7 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ let parameters = (ins CIR_VectorElementType:$elementType, "uint64_t":$size, - OptionalParameter<"bool">:$isScalable + OptionalParameter<"bool">:$is_scalable ); let assemblyFormat = [{ From f9bdf12337e9b26460e25df8168dda50fdbf03a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= <[email protected]> Date: Tue, 16 Dec 2025 13:50:36 +0000 Subject: [PATCH 4/9] Update clang/include/clang/CIR/Dialect/IR/CIRTypes.td Co-authored-by: Andy Kaylor <[email protected]> --- clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 8e1f288eab822..41f1ca8d3f295 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -445,7 +445,7 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ }]; let parameters = (ins - CIR_VectorElementType:$elementType, + CIR_VectorElementType:$element_type, "uint64_t":$size, OptionalParameter<"bool">:$is_scalable ); From 51064ee89a887d8d498c2deca1a80e4a7974869c Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Tue, 16 Dec 2025 16:18:28 +0000 Subject: [PATCH 5/9] Address PR comments: * Fix `$elementType` spelling * Add `getFP` helpers and remove TODOs. * Fix: `builder.createAMul` --> `builder.createNUWAMul` --- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 6 +- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 5 + .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 4 +- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 28 ++-- .../CodeGenBuiltins/AArch64/acle_sve_len.c | 121 +++++++++++------- clang/test/CIR/IR/invalid-vector.cir | 2 +- 6 files changed, 101 insertions(+), 65 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 41f1ca8d3f295..b553b83cf0b15 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -451,15 +451,15 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ ); let assemblyFormat = [{ - `<` $size `x` $elementType `>` + `<` $size `x` $element_type `>` }]; let builders = [ TypeBuilderWithInferredContext<(ins - "mlir::Type":$elementType, "uint64_t":$size, CArg<"bool", + "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool", "false">:$isScalable ), [{ - return $_get(elementType.getContext(), elementType, size, isScalable); + return $_get(element_type.getContext(), element_type, size, isScalable); }]>, ]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 2a15b1f7703be..8acad5278b732 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); diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 7a9661b727dc7..162c466759b8a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -59,8 +59,8 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, StringRef intrinsicName = "vscale.i64"; auto vscale = emitIntrinsicCallOp(builder, loc, intrinsicName, convertType(expr->getType())); - return builder.createMul(loc, vscale, - builder.getUInt64(scalingFactor, loc)); + return builder.createNUWAMul(loc, vscale, + builder.getUInt64(scalingFactor, loc)); }; assert(!cir::MissingFeatures::aarch64SVEIntrinsics()); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 3bb075d7581f7..67c7bb18716db 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -339,10 +339,14 @@ mlir::Type CIRGenTypes::convertType(QualType type) { resultType = cir::VectorType::get(builder.getUInt16Ty(), 8, /*isScalable=*/true); break; - // TODO: Waiting for FP type helpers - // case BuiltinType::SveFloat16: - // resultType = cir::VectorType::get(builder.getF16Type(), 8, - // /*isScalable=*/true); break; + case BuiltinType::SveFloat16: + resultType = cir::VectorType::get(builder.getFp16Ty(), 8, + /*isScalable=*/true); + break; + case BuiltinType::SveBFloat16: + resultType = cir::VectorType::get(builder.getFp16Ty(), 8, + /*isScalable=*/true); + break; case BuiltinType::SveInt32: resultType = cir::VectorType::get(builder.getSInt32Ty(), 4, /*isScalable=*/true); @@ -351,10 +355,10 @@ mlir::Type CIRGenTypes::convertType(QualType type) { resultType = cir::VectorType::get(builder.getUInt32Ty(), 4, /*isScalable=*/true); break; - // TODO: Waiting for FP type helpers - // case BuiltinType::SveFloat32: - // resultType = cir::VectorType::get(builder.getF32Type(), 4, - // /*isScalable=*/true); break; + case BuiltinType::SveFloat32: + resultType = cir::VectorType::get(builder.getSingleTy(), 4, + /*isScalable=*/true); + break; case BuiltinType::SveInt64: resultType = cir::VectorType::get(builder.getSInt64Ty(), 2, /*isScalable=*/true); @@ -363,10 +367,10 @@ mlir::Type CIRGenTypes::convertType(QualType type) { resultType = cir::VectorType::get(builder.getUInt64Ty(), 2, /*isScalable=*/true); break; - // TODO: Waiting for FP type helpers - // case BuiltinType::SveFloat64: - // resultType = cir::VectorType::get(builder.getF64Type(), 2, - // /*isScalable=*/true); break; + case BuiltinType::SveFloat64: + resultType = cir::VectorType::get(builder.getDoubleTy(), 2, + /*isScalable=*/true); + break; // Unsigned integral types. case BuiltinType::Char8: diff --git a/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c index 3ad2ddef04030..0bacdbb151cd8 100644 --- a/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c +++ b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c @@ -3,9 +3,12 @@ // 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 -// 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 + +// 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> @@ -27,10 +30,10 @@ uint64_t test_svlen_u8(svuint8_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C16:.*]] = cir.const #cir.int<16> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 16 +// 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); } @@ -39,10 +42,10 @@ uint64_t test_svlen_s8(svint8_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C16:.*]] = cir.const #cir.int<16> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C16]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 16 +// 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); } @@ -51,10 +54,10 @@ uint64_t test_svlen_u16(svuint16_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C8:.*]] = cir.const #cir.int<8> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 8 +// 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); } @@ -63,34 +66,46 @@ uint64_t test_svlen_s16(svint16_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C8:.*]] = cir.const #cir.int<8> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 8 +// 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); } -// TODO: Waiting for FP type helpers -// uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR -// { -// return SVE_ACLE_FUNC(svlen,_f16,,)(op); -// } +// ALL-LABEL: @test_svlen_f16( +uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR +{ +// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !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.i64" : () -> !u64i +// CIR: %[[C8:.*]] = cir.const #cir.int<8> : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C8]]) nuw : !u64i -// TODO: Waiting for FP type helpers -// uint64_t test_svlen_bf16(svbfloat16_t op) MODE_ATTR -// { -// return SVE_ACLE_FUNC(svlen,_bf16,,)(op); -// } +// 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.i64" : () -> !u64i // CIR: %[[C4:.*]] = cir.const #cir.int<4> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 4 +// 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); } @@ -99,28 +114,34 @@ uint64_t test_svlen_s32(svint32_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C4:.*]] = cir.const #cir.int<4> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C4]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 4 +// 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); } -// TODO: Waiting for FP type helpers -// uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR -// { -// return SVE_ACLE_FUNC(svlen,_f32,,)(op); -// } +// ALL-LABEL: @test_svlen_f32( +uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR +{ +// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !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.i64" : () -> !u64i // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 2 +// 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); } @@ -129,15 +150,21 @@ uint64_t test_svlen_s64(svint64_t op) MODE_ATTR { // CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !u64i -// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) : !u64i +// CIR: %[[BINOP:.*]] = cir.binop(mul, %[[VSCALE]], %[[C2]]) nuw : !u64i -// LLVM: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() -// LLVM: [[RES:%.*]] = mul i64 [[VSCALE]], 2 +// 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); } -// TODO: Waiting for FP type helpers -// uint64_t test_svlen_f64(svfloat64_t op) MODE_ATTR -// { -// return SVE_ACLE_FUNC(svlen,_f64,,)(op); -// } +// ALL-LABEL: @test_svlen_f64 +uint64_t test_svlen_f64(svfloat64_t op) MODE_ATTR +{ +// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !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>> } From 220de86345523b63ea06525cba85bfa78774b1d2 Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Tue, 16 Dec 2025 16:53:24 +0000 Subject: [PATCH 6/9] Address PR comments * Replace `vscaleTimesFactor` lambda with a static function: `genVscaleTimesFactor` * Replace `"vscale.i64"` with `"vscale"`. --- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 9 +++--- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 30 ++++++++++--------- .../CodeGenBuiltins/AArch64/acle_sve_len.c | 24 +++++++-------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index b553b83cf0b15..d9be7afcb7559 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -454,11 +454,10 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ `<` $size `x` $element_type `>` }]; - let builders = [ - TypeBuilderWithInferredContext<(ins - "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool", - "false">:$isScalable - ), [{ + let builders = [TypeBuilderWithInferredContext< + (ins "mlir::Type":$element_type, "uint64_t":$size, + CArg<"bool", "false">:$isScalable), + [{ return $_get(element_type.getContext(), element_type, size, isScalable); }]>, ]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 162c466759b8a..36852c03546e9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -42,6 +42,16 @@ static mlir::Value emitIntrinsicCallOp(CIRGenBuilderTy &builder, .getResult(); } +// Generate vscale * scalingFactor +static mlir::Value genVscaleTimesFactor(mlir::Location loc, + CIRGenBuilderTy builder, + mlir::Type cirTy, + int32_t scalingFactor) { + auto 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) { @@ -53,22 +63,14 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, return mlir::Value{}; } - mlir::Location loc = getLoc(expr->getExprLoc()); - // Generate vscale * scalingFactor - auto vscaleTimesFactor = [&](int32_t scalingFactor) { - StringRef intrinsicName = "vscale.i64"; - auto vscale = emitIntrinsicCallOp(builder, loc, intrinsicName, - convertType(expr->getType())); - return builder.createNUWAMul(loc, vscale, - builder.getUInt64(scalingFactor, loc)); - }; - assert(!cir::MissingFeatures::aarch64SVEIntrinsics()); switch (builtinID) { default: return std::nullopt; + mlir::Location loc = getLoc(expr->getExprLoc()); + case SVE::BI__builtin_sve_svreinterpret_b: case SVE::BI__builtin_sve_svreinterpret_c: case SVE::BI__builtin_sve_svpsel_lane_b8: @@ -129,20 +131,20 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, return mlir::Value{}; case SVE::BI__builtin_sve_svlen_u8: case SVE::BI__builtin_sve_svlen_s8: - return vscaleTimesFactor(16); + 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 vscaleTimesFactor(8); + 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 vscaleTimesFactor(4); + 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 vscaleTimesFactor(2); + 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/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c index 0bacdbb151cd8..ac202ef792ff9 100644 --- a/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c +++ b/clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c @@ -28,7 +28,7 @@ // ALL-LABEL: @test_svlen_u8 uint64_t test_svlen_u8(svuint8_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -40,7 +40,7 @@ uint64_t test_svlen_u8(svuint8_t op) MODE_ATTR // ALL-LABEL: @test_svlen_s8( uint64_t test_svlen_s8(svint8_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -52,7 +52,7 @@ uint64_t test_svlen_s8(svint8_t op) MODE_ATTR // ALL-LABEL: @test_svlen_u16( uint64_t test_svlen_u16(svuint16_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -64,7 +64,7 @@ uint64_t test_svlen_u16(svuint16_t op) MODE_ATTR // ALL-LABEL: @test_svlen_s16( uint64_t test_svlen_s16(svint16_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -76,7 +76,7 @@ uint64_t test_svlen_s16(svint16_t op) MODE_ATTR // ALL-LABEL: @test_svlen_f16( uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -88,7 +88,7 @@ uint64_t test_svlen_f16(svfloat16_t op) MODE_ATTR // ALL-LABEL: @test_svlen_bf16( uint64_t test_svlen_bf16(svbfloat16_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -100,7 +100,7 @@ uint64_t test_svlen_bf16(svbfloat16_t op) MODE_ATTR // ALL-LABEL: @test_svlen_u32( uint64_t test_svlen_u32(svuint32_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -112,7 +112,7 @@ uint64_t test_svlen_u32(svuint32_t op) MODE_ATTR // ALL-LABEL: @test_svlen_s32( uint64_t test_svlen_s32(svint32_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -124,7 +124,7 @@ uint64_t test_svlen_s32(svint32_t op) MODE_ATTR // ALL-LABEL: @test_svlen_f32( uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -136,7 +136,7 @@ uint64_t test_svlen_f32(svfloat32_t op) MODE_ATTR // ALL-LABEL: @test_svlen_u64( uint64_t test_svlen_u64(svuint64_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -148,7 +148,7 @@ uint64_t test_svlen_u64(svuint64_t op) MODE_ATTR // ALL-LABEL: @test_svlen_s64 uint64_t test_svlen_s64(svint64_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 @@ -160,7 +160,7 @@ uint64_t test_svlen_s64(svint64_t op) MODE_ATTR // ALL-LABEL: @test_svlen_f64 uint64_t test_svlen_f64(svfloat64_t op) MODE_ATTR { -// CIR: %[[VSCALE:.*]] = cir.call_llvm_intrinsic "vscale.i64" : () -> !u64i +// 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 From e1c40d24f6b6d90bb82310e706c587df0d4e339b Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Tue, 16 Dec 2025 16:59:09 +0000 Subject: [PATCH 7/9] Revert TD change --- clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index d9be7afcb7559..b553b83cf0b15 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -454,10 +454,11 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ `<` $size `x` $element_type `>` }]; - let builders = [TypeBuilderWithInferredContext< - (ins "mlir::Type":$element_type, "uint64_t":$size, - CArg<"bool", "false">:$isScalable), - [{ + let builders = [ + TypeBuilderWithInferredContext<(ins + "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool", + "false">:$isScalable + ), [{ return $_get(element_type.getContext(), element_type, size, isScalable); }]>, ]; From 589efc8758912926e3bc68025298e57da02e6747 Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Wed, 17 Dec 2025 09:27:10 +0000 Subject: [PATCH 8/9] Address final PR comments --- clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 4 ++-- clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index b553b83cf0b15..ce64bef3270ed 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -457,9 +457,9 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [ let builders = [ TypeBuilderWithInferredContext<(ins "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool", - "false">:$isScalable + "false">:$is_scalable ), [{ - return $_get(element_type.getContext(), element_type, size, isScalable); + return $_get(element_type.getContext(), element_type, size, is_scalable); }]>, ]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 36852c03546e9..e28b3c6cdc2ff 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -47,7 +47,7 @@ static mlir::Value genVscaleTimesFactor(mlir::Location loc, CIRGenBuilderTy builder, mlir::Type cirTy, int32_t scalingFactor) { - auto vscale = emitIntrinsicCallOp(builder, loc, "vscale", cirTy); + mlir::Value vscale = emitIntrinsicCallOp(builder, loc, "vscale", cirTy); return builder.createNUWAMul(loc, vscale, builder.getUInt64(scalingFactor, loc)); } @@ -65,12 +65,12 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, assert(!cir::MissingFeatures::aarch64SVEIntrinsics()); + mlir::Location loc = getLoc(expr->getExprLoc()); + switch (builtinID) { default: return std::nullopt; - mlir::Location loc = getLoc(expr->getExprLoc()); - case SVE::BI__builtin_sve_svreinterpret_b: case SVE::BI__builtin_sve_svreinterpret_c: case SVE::BI__builtin_sve_svpsel_lane_b8: From 5ff7fb284c5df4eefd7939c9fbf2fe0f749418bc Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Wed, 17 Dec 2025 10:46:47 +0000 Subject: [PATCH 9/9] Fix formatting --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 3 ++- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 24 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 696ffa42107e8..69769ac6dcd46 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -596,7 +596,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { VectorType vecCast = mlir::cast<VectorType>(lhs.getType()); IntType integralTy = getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType())); - VectorType integralVecTy = cir::VectorType::get(integralTy, vecCast.getSize()); + VectorType integralVecTy = + cir::VectorType::get(integralTy, vecCast.getSize()); return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs); } diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 67c7bb18716db..2e0193ac71e49 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -325,51 +325,51 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // SVE types case BuiltinType::SveInt8: resultType = - cir::VectorType::get(builder.getSInt8Ty(), 16, /*isScalable=*/true); + cir::VectorType::get(builder.getSInt8Ty(), 16, /*is_scalable=*/true); break; case BuiltinType::SveUint8: resultType = - cir::VectorType::get(builder.getUInt8Ty(), 16, /*isScalable=*/true); + cir::VectorType::get(builder.getUInt8Ty(), 16, /*is_scalable=*/true); break; case BuiltinType::SveInt16: resultType = - cir::VectorType::get(builder.getSInt16Ty(), 8, /*isScalable=*/true); + cir::VectorType::get(builder.getSInt16Ty(), 8, /*is_scalable=*/true); break; case BuiltinType::SveUint16: resultType = - cir::VectorType::get(builder.getUInt16Ty(), 8, /*isScalable=*/true); + cir::VectorType::get(builder.getUInt16Ty(), 8, /*is_scalable=*/true); break; case BuiltinType::SveFloat16: resultType = cir::VectorType::get(builder.getFp16Ty(), 8, - /*isScalable=*/true); + /*is_scalable=*/true); break; case BuiltinType::SveBFloat16: resultType = cir::VectorType::get(builder.getFp16Ty(), 8, - /*isScalable=*/true); + /*is_scalable=*/true); break; case BuiltinType::SveInt32: resultType = - cir::VectorType::get(builder.getSInt32Ty(), 4, /*isScalable=*/true); + cir::VectorType::get(builder.getSInt32Ty(), 4, /*is_scalable=*/true); break; case BuiltinType::SveUint32: resultType = - cir::VectorType::get(builder.getUInt32Ty(), 4, /*isScalable=*/true); + cir::VectorType::get(builder.getUInt32Ty(), 4, /*is_scalable=*/true); break; case BuiltinType::SveFloat32: resultType = cir::VectorType::get(builder.getSingleTy(), 4, - /*isScalable=*/true); + /*is_scalable=*/true); break; case BuiltinType::SveInt64: resultType = - cir::VectorType::get(builder.getSInt64Ty(), 2, /*isScalable=*/true); + cir::VectorType::get(builder.getSInt64Ty(), 2, /*is_scalable=*/true); break; case BuiltinType::SveUint64: resultType = - cir::VectorType::get(builder.getUInt64Ty(), 2, /*isScalable=*/true); + cir::VectorType::get(builder.getUInt64Ty(), 2, /*is_scalable=*/true); break; case BuiltinType::SveFloat64: resultType = cir::VectorType::get(builder.getDoubleTy(), 2, - /*isScalable=*/true); + /*is_scalable=*/true); break; // Unsigned integral types. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
