https://github.com/pawosm-arm updated https://github.com/llvm/llvm-project/pull/205432
>From 0813d38a5ddbdffa4a0aee40ae5874b698e48f72 Mon Sep 17 00:00:00 2001 From: Paul Osmialowski <[email protected]> Date: Tue, 23 Jun 2026 20:30:20 +0000 Subject: [PATCH] [clang][Sema] Allow splat initialization of a sizeless vector in a C++ code Consider the following C++ code: ``` typedef int8_t vint8x8 __attribute__((ext_vector_type(8U))); vint8x8 vint8x8_fun(void) { vint8x8 vint8x8var(123); return vint8x8var; } ``` The `vint8x8 vi8x8(123);` initialization results in a splat operation: ``` define dso_local <8 x i8> @vint8x8_fun() #0 { entry: %vint8x8var = alloca <8 x i8>, align 8 store <8 x i8> splat (i8 123), ptr %vint8x8var, align 8 %0 = load <8 x i8>, ptr %vint8x8var, align 8 ret <8 x i8> %0 } ``` Unfortunately, similar C++ code with a sizeless vector type: ``` __SVInt8_t __SVInt8_t_fun(void) { __SVInt8_t __SVInt8_t_var(123); return __SVInt8_t_var; } ``` ...would result in an error message like this: ``` error: cannot initialize a variable of type '__SVInt8_t' with an rvalue of type 'int' ``` This patch enables generation of the splat instead: ``` define dso_local <vscale x 16 x i8> @__SVInt8_t_fun() #0 { entry: %__SVInt8_t_var = alloca <vscale x 16 x i8>, align 16 store <vscale x 16 x i8> splat (i8 123), ptr %__SVInt8_t_var, align 16 %0 = load <vscale x 16 x i8>, ptr %__SVInt8_t_var, align 16 ret <vscale x 16 x i8> %0 } ``` --- clang/lib/Sema/SemaExpr.cpp | 9 +- clang/lib/Sema/SemaInit.cpp | 20 +- clang/lib/Sema/SemaOverload.cpp | 9 + .../CodeGen/sizeless-splat-init-aarch64.cpp | 188 ++++++++++++++++++ .../CodeGen/sizeless-splat-init-riscv.cpp | 188 ++++++++++++++++++ clang/test/SemaCXX/sizeless-1.cpp | 6 +- 6 files changed, 414 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/sizeless-splat-init-aarch64.cpp create mode 100644 clang/test/CodeGen/sizeless-splat-init-riscv.cpp diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cd95ec311218..529e5357d934b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8057,7 +8057,14 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, } ExprResult Sema::prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr) { - QualType DestElemTy = VectorTy->castAs<VectorType>()->getElementType(); + QualType DestElemTy = + VectorTy->isSizelessVectorType() + ? VectorTy->isSveVLSBuiltinType() || VectorTy->isRVVVLSBuiltinType() + ? Context + .getBuiltinVectorTypeInfo(VectorTy->castAs<BuiltinType>()) + .ElementType + : VectorTy->getSizelessVectorEltType(Context) + : VectorTy->castAs<VectorType>()->getElementType(); if (DestElemTy == SplattedExpr->getType()) return SplattedExpr; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index dad9c8c972dd9..19c3dbad85345 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1484,8 +1484,24 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, } else if (DeclType->isOCLIntelSubgroupAVCType() || DeclType->isSizelessBuiltinType()) { // Checks for scalar type are sufficient for these types too. - CheckScalarType(Entity, IList, DeclType, Index, StructuredList, - StructuredIndex); + Expr *expr = + (Index < IList->getNumInits()) ? IList->getInit(Index) : nullptr; + // Prevent splat when doing list initialization. + if (expr && expr->getType()->isArithmeticType() && + DeclType->isSizelessVectorType() && + SemaRef.Context.getLangOpts().CPlusPlus) { + if (!VerifyOnly) { + PartialDiagnostic PDiag = + SemaRef.PDiag(diag::err_init_conversion_failed) + << static_cast<int>(Entity.getKind()) << DeclType + << expr->isLValue() << expr->getType() << expr->getSourceRange(); + SemaRef.HandleFunctionTypeMismatch(PDiag, expr->getType(), DeclType); + SemaRef.Diag(expr->getBeginLoc(), PDiag); + } + hadError = true; + } else + CheckScalarType(Entity, IList, DeclType, Index, StructuredList, + StructuredIndex); } else if (DeclType->isDependentType()) { // C++ [over.match.class.deduct]p1.5: // brace elision is not considered for any aggregate element that has a diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c663765573612..c837641b20084 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2203,6 +2203,15 @@ static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType, ImplicitConversionKind &ICK, ImplicitConversionKind &ElConv, Expr *From, bool InOverloadResolution, bool CStyle) { + // A special treatment is needed when targeting a sizeless vector type. + if (ToType->isSizelessVectorType()) { + // Vector splat from any arithmetic type to a sizeless vector. + if (FromType->isArithmeticType() && S.getLangOpts().CPlusPlus) { + ICK = ICK_Vector_Splat; + return true; + } + } + // We need at least one of these types to be a vector type to have a vector // conversion. if (!ToType->isVectorType() && !FromType->isVectorType()) diff --git a/clang/test/CodeGen/sizeless-splat-init-aarch64.cpp b/clang/test/CodeGen/sizeless-splat-init-aarch64.cpp new file mode 100644 index 0000000000000..a394728a3200b --- /dev/null +++ b/clang/test/CodeGen/sizeless-splat-init-aarch64.cpp @@ -0,0 +1,188 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +sve %s -emit-llvm -o - | FileCheck %s + +#include <stdint.h> + +// CHECK-LABEL: __SVBool_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i1> splat (i1 true), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__SVBool_t __SVBool_t_fun_1(void) { + __SVBool_t svi1(true); + return svi1; +} + +// CHECK-LABEL: __SVBool_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i1> splat (i1 true), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__SVBool_t __SVBool_t_fun_2(void) { + __SVBool_t svi1 = true; + return svi1; +} + +// CHECK-LABEL: __SVBool_t_argfun_1 +// CHECK: %[[STOREDV:.*]] = zext i1 %arg to i8 +// CHECK: store i8 %[[STOREDV]], ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i8, ptr %[[WHERE]] +// CHECK: %[[WHAT_I1:.*]] = icmp ne i8 %[[WHAT]], 0 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i1> poison, i1 %[[WHAT_I1]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i1> %[[INSERT]], <vscale x {{[0-9]*}} x i1> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i1> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__SVBool_t __SVBool_t_argfun_1(bool arg) { + __SVBool_t svi1(arg); + return svi1; +} + +void __SVBool_t_sink(__SVBool_t); + +// CHECK-LABEL: __SVBool_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_I1:.*]] = icmp ne i32 %[[WHAT]], 0 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i1> poison, i1 %[[WHAT_I1]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i1> %[[INSERT]], <vscale x {{[0-9]*}} x i1> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i1> %[[SPLAT]]) +// CHECK: ret void +void __SVBool_t_argfun_2(int i) +{ + __SVBool_t_sink(i); +} + +// CHECK-LABEL: __SVInt8_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i8> splat (i8 123), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__SVInt8_t __SVInt8_t_fun_1(void) { + __SVInt8_t svi8(123); + return svi8; +} + +// CHECK-LABEL: __SVInt8_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i8> splat (i8 123), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__SVInt8_t __SVInt8_t_fun_2(void) { + __SVInt8_t svi8 = 123; + return svi8; +} + +// CHECK-LABEL: __SVInt8_t_argfun_1 +// CHECK: store i8 %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i8, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i8> poison, i8 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i8> %[[INSERT]], <vscale x {{[0-9]*}} x i8> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i8> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__SVInt8_t __SVInt8_t_argfun_1(int8_t arg) { + __SVInt8_t svi8(arg); + return svi8; +} + +void __SVInt8_t_sink(__SVInt8_t); + +// CHECK-LABEL __SVInt8_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_I8:.*]] = trunc i32 %[[WHAT]] to i8 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i8> poison, i8 %[[WHAT_I8]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i8> %[[INSERT]], <vscale x {{[0-9]*}} x i8> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i8> %[[SPLAT]]) +// CHECK: ret void +void __SVInt8_t_argfun_2(int i) +{ + __SVInt8_t_sink(i); +} + +// CHECK-LABEL: __SVUint32_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i32> splat (i32 1024), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__SVUint32_t __SVUint32_t_fun_1(void) { + __SVUint32_t svui32(1024U); + return svui32; +} + +// CHECK-LABEL: __SVUint32_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i32> splat (i32 1024), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__SVUint32_t __SVUint32_t_fun_2(void) { + __SVUint32_t svui32 = 1024U; + return svui32; +} + +// CHECK-LABEL: __SVUint32_t_argfun_1 +// CHECK: store i32 %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i32> poison, i32 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i32> %[[INSERT]], <vscale x {{[0-9]*}} x i32> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i32> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__SVUint32_t __SVUint32_t_argfun_1(uint32_t arg) { + __SVUint32_t svui32(arg); + return svui32; +} + +void __SVUint32_t_sink(__SVUint32_t); + +// CHECK-LABEL: __SVUint32_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i32> poison, i32 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i32> %[[INSERT]], <vscale x {{[0-9]*}} x i32> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i32> %[[SPLAT]]) +// CHECK: ret void +void __SVUint32_t_argfun_2(int i) +{ + __SVUint32_t_sink(i); +} + +// CHECK-LABEL: __SVFloat32_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x float> splat (float 1.230000e-01), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__SVFloat32_t __SVFloat32_t_fun_1(void) { + __SVFloat32_t svfloat32(0.123); + return svfloat32; +} + +// CHECK-LABEL: __SVFloat32_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x float> splat (float 1.230000e-01), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__SVFloat32_t __SVFloat32_t_fun_2(void) { + __SVFloat32_t svfloat32 = 0.123; + return svfloat32; +} + +// CHECK-LABEL: __SVFloat32_t_argfun_1 +// CHECK: store float %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load float, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x float> poison, float %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x float> %[[INSERT]], <vscale x {{[0-9]*}} x float> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x float> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__SVFloat32_t __SVFloat32_t_argfun_1(float arg) { + __SVFloat32_t svfloat32(arg); + return svfloat32; +} + +void __SVFloat32_t_sink(__SVFloat32_t); + +// CHECK-LABEL: __SVFloat32_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_FP:.*]] = sitofp i32 %[[WHAT]] to float +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x float> poison, float %[[WHAT_FP]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x float> %[[INSERT]], <vscale x {{[0-9]*}} x float> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x float> %[[SPLAT]]) +// CHECK: ret void +void __SVFloat32_t_argfun_2(int i) +{ + __SVFloat32_t_sink(i); +} diff --git a/clang/test/CodeGen/sizeless-splat-init-riscv.cpp b/clang/test/CodeGen/sizeless-splat-init-riscv.cpp new file mode 100644 index 0000000000000..3b7e0f6c70204 --- /dev/null +++ b/clang/test/CodeGen/sizeless-splat-init-riscv.cpp @@ -0,0 +1,188 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +zve64d %s -emit-llvm -o - | FileCheck %s + +#include <stdint.h> + +// CHECK-LABEL: __rvv_bool1_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i1> splat (i1 true), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__rvv_bool1_t __rvv_bool1_t_fun_1(void) { + __rvv_bool1_t svi1(true); + return svi1; +} + +// CHECK-LABEL: __rvv_bool1_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i1> splat (i1 true), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__rvv_bool1_t __rvv_bool1_t_fun_2(void) { + __rvv_bool1_t svi1 = true; + return svi1; +} + +// CHECK-LABEL: __rvv_bool1_t_argfun_1 +// CHECK: %[[STOREDV:.*]] = zext i1 %arg to i8 +// CHECK: store i8 %[[STOREDV]], ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i8, ptr %[[WHERE]] +// CHECK: %[[WHAT_I1:.*]] = icmp ne i8 %[[WHAT]], 0 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i1> poison, i1 %[[WHAT_I1]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i1> %[[INSERT]], <vscale x {{[0-9]*}} x i1> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i1> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i1>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i1> %[[RETVAL]] +__rvv_bool1_t __rvv_bool1_t_argfun_1(bool arg) { + __rvv_bool1_t svi1(arg); + return svi1; +} + +void __rvv_bool1_t_sink(__rvv_bool1_t); + +// CHECK-LABEL: __rvv_bool1_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_I1:.*]] = icmp ne i32 %[[WHAT]], 0 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i1> poison, i1 %[[WHAT_I1]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i1> %[[INSERT]], <vscale x {{[0-9]*}} x i1> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i1> %[[SPLAT]]) +// CHECK: ret void +void __rvv_bool1_t_argfun_2(int i) +{ + __rvv_bool1_t_sink(i); +} + +// CHECK-LABEL: __rvv_int8m1_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i8> splat (i8 123), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__rvv_int8m1_t __rvv_int8m1_t_fun_1(void) { + __rvv_int8m1_t svi8(123); + return svi8; +} + +// CHECK-LABEL: __rvv_int8m1_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i8> splat (i8 123), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__rvv_int8m1_t __rvv_int8m1_t_fun_2(void) { + __rvv_int8m1_t svi8 = 123; + return svi8; +} + +// CHECK-LABEL: __rvv_int8m1_t_argfun_1 +// CHECK: store i8 %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i8, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i8> poison, i8 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i8> %[[INSERT]], <vscale x {{[0-9]*}} x i8> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i8> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i8>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i8> %[[RETVAL]] +__rvv_int8m1_t __rvv_int8m1_t_argfun_1(int8_t arg) { + __rvv_int8m1_t svi8(arg); + return svi8; +} + +void __rvv_int8m1_t_sink(__rvv_int8m1_t); + +// CHECK-LABEL __rvv_int8m1_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_I8:.*]] = trunc i32 %[[WHAT]] to i8 +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i8> poison, i8 %[[WHAT_I8]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i8> %[[INSERT]], <vscale x {{[0-9]*}} x i8> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i8> %[[SPLAT]]) +// CHECK: ret void +void __rvv_int8m1_t_argfun_2(int i) +{ + __rvv_int8m1_t_sink(i); +} + +// CHECK-LABEL: __rvv_uint32m1_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x i32> splat (i32 1024), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__rvv_uint32m1_t __rvv_uint32m1_t_fun_1(void) { + __rvv_uint32m1_t svui32(1024U); + return svui32; +} + +// CHECK-LABEL: __rvv_uint32m1_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x i32> splat (i32 1024), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__rvv_uint32m1_t __rvv_uint32m1_t_fun_2(void) { + __rvv_uint32m1_t svui32 = 1024U; + return svui32; +} + +// CHECK-LABEL: __rvv_uint32m1_t_argfun_1 +// CHECK: store i32 %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i32> poison, i32 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i32> %[[INSERT]], <vscale x {{[0-9]*}} x i32> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x i32> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x i32>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x i32> %[[RETVAL]] +__rvv_uint32m1_t __rvv_uint32m1_t_argfun_1(uint32_t arg) { + __rvv_uint32m1_t svui32(arg); + return svui32; +} + +void __rvv_uint32m1_t_sink(__rvv_uint32m1_t); + +// CHECK-LABEL: __rvv_uint32m1_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x i32> poison, i32 %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x i32> %[[INSERT]], <vscale x {{[0-9]*}} x i32> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x i32> %[[SPLAT]]) +// CHECK: ret void +void __rvv_uint32m1_t_argfun_2(int i) +{ + __rvv_uint32m1_t_sink(i); +} + +// CHECK-LABEL: __rvv_float32m1_t_fun_1 +// CHECK: store <vscale x {{[0-9]*}} x float> splat (float 1.230000e-01), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__rvv_float32m1_t __rvv_float32m1_t_fun_1(void) { + __rvv_float32m1_t svfloat32(0.123); + return svfloat32; +} + +// CHECK-LABEL: __rvv_float32m1_t_fun_2 +// CHECK: store <vscale x {{[0-9]*}} x float> splat (float 1.230000e-01), ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__rvv_float32m1_t __rvv_float32m1_t_fun_2(void) { + __rvv_float32m1_t svfloat32 = 0.123; + return svfloat32; +} + +// CHECK-LABEL: __rvv_float32m1_t_argfun_1 +// CHECK: store float %arg, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load float, ptr %[[WHERE]] +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x float> poison, float %[[WHAT]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x float> %[[INSERT]], <vscale x {{[0-9]*}} x float> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: store <vscale x {{[0-9]*}} x float> %[[SPLAT]], ptr %[[RETPTR:.*]] +// CHECK: %[[RETVAL:.*]] = load <vscale x {{[0-9]*}} x float>, ptr %[[RETPTR]] +// CHECK: ret <vscale x {{[0-9]*}} x float> %[[RETVAL]] +__rvv_float32m1_t __rvv_float32m1_t_argfun_1(float arg) { + __rvv_float32m1_t svfloat32(arg); + return svfloat32; +} + +void __rvv_float32m1_t_sink(__rvv_float32m1_t); + +// CHECK-LABEL: __rvv_float32m1_t_argfun_2 +// CHECK: store i32 %i, ptr %[[WHERE:.*]] +// CHECK: %[[WHAT:.*]] = load i32, ptr %[[WHERE]] +// CHECK: %[[WHAT_FP:.*]] = sitofp i32 %[[WHAT]] to float +// CHECK: %[[INSERT:.*]] = insertelement <vscale x {{[0-9]*}} x float> poison, float %[[WHAT_FP]], i64 0 +// CHECK: %[[SPLAT:.*]] = shufflevector <vscale x {{[0-9]*}} x float> %[[INSERT]], <vscale x {{[0-9]*}} x float> poison, <vscale x {{[0-9]*}} x i32> zeroinitializer +// CHECK: call void @[[SINK:.*]](<vscale x {{[0-9]*}} x float> %[[SPLAT]]) +// CHECK: ret void +void __rvv_float32m1_t_argfun_2(int i) +{ + __rvv_float32m1_t_sink(i); +} diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp index ef3eec9507b58..880880f973235 100644 --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -127,14 +127,14 @@ void func(int sel) { init_int8 = local_int8; init_int8 = local_int16; // expected-error {{assigning to 'svint8_t' (aka '__SVInt8_t') from incompatible type 'svint16_t'}} - init_int8 = sel; // expected-error {{assigning to 'svint8_t' (aka '__SVInt8_t') from incompatible type 'int'}} + init_int8 = sel; sel = local_int8; // expected-error {{assigning to 'int' from incompatible type 'svint8_t'}} local_int8 = (svint8_t)local_int8; local_int8 = (const svint8_t)local_int8; local_int8 = (svint8_t)local_int16; // expected-error {{C-style cast from 'svint16_t' (aka '__SVInt16_t') to 'svint8_t' (aka '__SVInt8_t') is not allowed}} - local_int8 = (svint8_t)0; // expected-error {{C-style cast from 'int' to 'svint8_t' (aka '__SVInt8_t') is not allowed}} + local_int8 = (svint8_t)0; sel = (int)local_int8; // expected-error {{C-style cast from 'svint8_t' (aka '__SVInt8_t') to 'int' is not allowed}} init_int8 = local_int8; @@ -354,7 +354,7 @@ void cxx_only(int sel) { local_int8 = static_cast<svint8_t>(local_int8); local_int8 = static_cast<svint8_t>(local_int16); // expected-error {{static_cast from 'svint16_t' (aka '__SVInt16_t') to 'svint8_t' (aka '__SVInt8_t') is not allowed}} - local_int8 = static_cast<svint8_t>(0); // expected-error {{static_cast from 'int' to 'svint8_t' (aka '__SVInt8_t') is not allowed}} + local_int8 = static_cast<svint8_t>(0); local_int16 = static_cast<svint16_t>(local_int8); // expected-error {{static_cast from 'svint8_t' (aka '__SVInt8_t') to 'svint16_t' (aka '__SVInt16_t') is not allowed}} sel = static_cast<int>(local_int8); // expected-error {{static_cast from 'svint8_t' (aka '__SVInt8_t') to 'int' is not allowed}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
