llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Craig Topper (topperc) <details> <summary>Changes</summary> This adopts a similar behavior to AArch64 SVE, where bool vectors are represented as a vector of chars with 1/8 the number of elements. This ensures the vector always occupies a power of 2 number of bytes. A consequence of this is that vbool64_t, vbool32_t, and vool16_t can only be used with a vector length that guarantees at least 8 bits. --- Patch is 91.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76551.diff 19 Files Affected: - (modified) clang/include/clang/AST/Type.h (+3) - (modified) clang/include/clang/Basic/AttrDocs.td (+4-1) - (modified) clang/lib/AST/ASTContext.cpp (+16-4) - (modified) clang/lib/AST/ItaniumMangle.cpp (+17-8) - (modified) clang/lib/AST/JSONNodeDumper.cpp (+3) - (modified) clang/lib/AST/TextNodeDumper.cpp (+3) - (modified) clang/lib/AST/Type.cpp (+14-1) - (modified) clang/lib/AST/TypePrinter.cpp (+2) - (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+15-6) - (modified) clang/lib/Sema/SemaExpr.cpp (+4-2) - (modified) clang/lib/Sema/SemaType.cpp (+15-6) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-bitcast.c (+100) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-call.c (+74) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-cast.c (+72-4) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-codegen.c (+172) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-globals.c (+107) - (modified) clang/test/CodeGen/attr-riscv-rvv-vector-bits-types.c (+284) - (modified) clang/test/CodeGenCXX/riscv-mangle-rvv-fixed-vectors.cpp (+72) - (modified) clang/test/Sema/attr-riscv-rvv-vector-bits.c (+86-2) ``````````diff diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1afa693672860f..82c4a5e8701fa5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -3492,6 +3492,9 @@ enum class VectorKind { /// is RISC-V RVV fixed-length data vector RVVFixedLengthData, + + /// is RISC-V RVV fixed-length mask vector + RVVFixedLengthMask, }; /// Represents a GCC generic vector type. This type is created using diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 98a7ecc7fd7df3..c4d69d5a50093c 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2415,7 +2415,10 @@ only be a power of 2 between 64 and 65536. For types where LMUL!=1, ``__riscv_v_fixed_vlen`` needs to be scaled by the LMUL of the type before passing to the attribute. -``vbool*_t`` types are not supported at this time. +For ``vbool*_t`` types, ``__riscv_v_fixed_vlen`` needs to be divided by the +number from the type name. For example, ``vbool8_t`` needs to use +``__riscv_v_fixed_vlen`` / 8. If the resulting value is not a multiple of 8, +the type is not supported for that value of ``__riscv_v_fixed_vlen``. }]; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0395b3e47ab6f8..97df251fef6442 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1938,7 +1938,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { else if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) // Adjust the alignment for fixed-length SVE predicates. Align = 16; - else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData) + else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || + VT->getVectorKind() == VectorKind::RVVFixedLengthMask) // Adjust the alignment for fixed-length RVV vectors. Align = std::min<unsigned>(64, Width); break; @@ -9404,7 +9405,9 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, Second->getVectorKind() != VectorKind::SveFixedLengthData && Second->getVectorKind() != VectorKind::SveFixedLengthPredicate && First->getVectorKind() != VectorKind::RVVFixedLengthData && - Second->getVectorKind() != VectorKind::RVVFixedLengthData) + Second->getVectorKind() != VectorKind::RVVFixedLengthData && + First->getVectorKind() != VectorKind::RVVFixedLengthMask && + Second->getVectorKind() != VectorKind::RVVFixedLengthMask) return true; return false; @@ -9510,8 +9513,11 @@ static uint64_t getRVVTypeSize(ASTContext &Context, const BuiltinType *Ty) { ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo(Ty); - uint64_t EltSize = Context.getTypeSize(Info.ElementType); - uint64_t MinElts = Info.EC.getKnownMinValue(); + unsigned EltSize = Context.getTypeSize(Info.ElementType); + if (Info.ElementType == Context.BoolTy) + EltSize = 1; + + unsigned MinElts = Info.EC.getKnownMinValue(); return VScale->first * MinElts * EltSize; } @@ -9525,6 +9531,12 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType, auto IsValidCast = [this](QualType FirstType, QualType SecondType) { if (const auto *BT = FirstType->getAs<BuiltinType>()) { if (const auto *VT = SecondType->getAs<VectorType>()) { + if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) { + BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT); + return FirstType->isRVVVLSBuiltinType() && + Info.ElementType == BoolTy && + getTypeSize(SecondType) == getRVVTypeSize(*this, BT); + } if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || VT->getVectorKind() == VectorKind::Generic) return FirstType->isRVVVLSBuiltinType() && diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b1678479888eb7..9e3642387b7a81 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3994,7 +3994,8 @@ void CXXNameMangler::mangleAArch64FixedSveVectorType( } void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { - assert(T->getVectorKind() == VectorKind::RVVFixedLengthData && + assert((T->getVectorKind() == VectorKind::RVVFixedLengthData || + T->getVectorKind() == VectorKind::RVVFixedLengthMask) && "expected fixed-length RVV vector!"); QualType EltType = T->getElementType(); @@ -4009,7 +4010,10 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { TypeNameOS << "int8"; break; case BuiltinType::UChar: - TypeNameOS << "uint8"; + if (T->getVectorKind() == VectorKind::RVVFixedLengthData) + TypeNameOS << "uint8"; + else + TypeNameOS << "bool"; break; case BuiltinType::Short: TypeNameOS << "int16"; @@ -4048,12 +4052,16 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { auto VScale = getASTContext().getTargetInfo().getVScaleRange( getASTContext().getLangOpts()); unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock; - TypeNameOS << 'm'; - if (VecSizeInBits >= VLen) - TypeNameOS << (VecSizeInBits / VLen); - else - TypeNameOS << 'f' << (VLen / VecSizeInBits); + if (T->getVectorKind() == VectorKind::RVVFixedLengthData) { + TypeNameOS << 'm'; + if (VecSizeInBits >= VLen) + TypeNameOS << (VecSizeInBits / VLen); + else + TypeNameOS << 'f' << (VLen / VecSizeInBits); + } else { + TypeNameOS << (VLen / VecSizeInBits); + } TypeNameOS << "_t"; Out << "9__RVV_VLSI" << 'u' << TypeNameStr.size() << TypeNameStr << "Lj" @@ -4093,7 +4101,8 @@ void CXXNameMangler::mangleType(const VectorType *T) { T->getVectorKind() == VectorKind::SveFixedLengthPredicate) { mangleAArch64FixedSveVectorType(T); return; - } else if (T->getVectorKind() == VectorKind::RVVFixedLengthData) { + } else if (T->getVectorKind() == VectorKind::RVVFixedLengthData || + T->getVectorKind() == VectorKind::RVVFixedLengthMask) { mangleRISCVFixedRVVVectorType(T); return; } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 637d06cee78c85..95b682c19fbe4a 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -703,6 +703,9 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) { case VectorKind::RVVFixedLengthData: JOS.attribute("vectorKind", "fixed-length rvv data vector"); break; + case VectorKind::RVVFixedLengthMask: + JOS.attribute("vectorKind", "fixed-length rvv mask vector"); + break; } } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index e8274fcd5cfe9c..9741fc792506b1 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1613,6 +1613,9 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) { case VectorKind::RVVFixedLengthData: OS << " fixed-length rvv data vector"; break; + case VectorKind::RVVFixedLengthMask: + OS << " fixed-length rvv mask vector"; + break; } OS << " " << T->getNumElements(); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 160a725939ccd4..774ca8e55fd5a8 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2479,6 +2479,9 @@ bool Type::isRVVVLSBuiltinType() const { IsFP, IsBF) \ case BuiltinType::Id: \ return NF == 1; +#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \ + case BuiltinType::Id: \ + return true; #include "clang/Basic/RISCVVTypes.def" default: return false; @@ -2491,7 +2494,17 @@ QualType Type::getRVVEltType(const ASTContext &Ctx) const { assert(isRVVVLSBuiltinType() && "unsupported type!"); const BuiltinType *BTy = castAs<BuiltinType>(); - return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType; + + switch (BTy->getKind()) { +#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \ + case BuiltinType::Id: \ + return Ctx.UnsignedCharTy; + default: + return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType; +#include "clang/Basic/RISCVVTypes.def" + } + + llvm_unreachable("Unhandled type"); } bool QualType::isPODType(const ASTContext &Context) const { diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index f6941242927367..70e0f2f97060c9 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -694,6 +694,7 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { printBefore(T->getElementType(), OS); break; case VectorKind::RVVFixedLengthData: + case VectorKind::RVVFixedLengthMask: // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. OS << "__attribute__((__riscv_rvv_vector_bits__("; @@ -773,6 +774,7 @@ void TypePrinter::printDependentVectorBefore( printBefore(T->getElementType(), OS); break; case VectorKind::RVVFixedLengthData: + case VectorKind::RVVFixedLengthMask: // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. OS << "__attribute__((__riscv_rvv_vector_bits__("; diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 1e1d249b37ac06..62257c600f7ec8 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -318,20 +318,28 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const { assert(Ty->isVectorType() && "expected vector type!"); const auto *VT = Ty->castAs<VectorType>(); - assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData && - "Unexpected vector kind"); - assert(VT->getElementType()->isBuiltinType() && "expected builtin type!"); auto VScale = getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts()); + + unsigned NumElts = VT->getNumElements(); + llvm::Type *EltType; + if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) { + NumElts *= 8; + EltType = llvm::Type::getInt1Ty(getVMContext()); + } else { + assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData && + "Unexpected vector kind"); + EltType = CGT.ConvertType(VT->getElementType()); + } + // The MinNumElts is simplified from equation: // NumElts / VScale = // (EltSize * NumElts / (VScale * RVVBitsPerBlock)) // * (RVVBitsPerBlock / EltSize) llvm::ScalableVectorType *ResType = - llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()), - VT->getNumElements() / VScale->first); + llvm::ScalableVectorType::get(EltType, NumElts / VScale->first); return ABIArgInfo::getDirect(ResType); } @@ -431,7 +439,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, } if (const VectorType *VT = Ty->getAs<VectorType>()) - if (VT->getVectorKind() == VectorKind::RVVFixedLengthData) + if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || + VT->getVectorKind() == VectorKind::RVVFixedLengthMask) return coerceVLSVector(Ty); // Aggregates which are <= 2*XLen will be passed in registers if possible, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 960f513d1111b2..498c49a76c000c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11167,7 +11167,8 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, if (VecType->getVectorKind() == VectorKind::SveFixedLengthData || VecType->getVectorKind() == VectorKind::SveFixedLengthPredicate) return true; - if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData) { + if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData || + VecType->getVectorKind() == VectorKind::RVVFixedLengthMask) { SVEorRVV = 1; return true; } @@ -11198,7 +11199,8 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, SecondVecType->getVectorKind() == VectorKind::SveFixedLengthPredicate) return true; - if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData) { + if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData || + SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask) { SVEorRVV = 1; return true; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a376f20fa4f4e0..834c4ddcccf5da 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8542,21 +8542,30 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, ASTContext::BuiltinVectorTypeInfo Info = S.Context.getBuiltinVectorTypeInfo(CurType->castAs<BuiltinType>()); - unsigned EltSize = S.Context.getTypeSize(Info.ElementType); unsigned MinElts = Info.EC.getKnownMinValue(); + VectorKind VecKind = VectorKind::RVVFixedLengthData; + unsigned ExpectedSize = VScale->first * MinElts; + QualType EltType = CurType->getRVVEltType(S.Context); + unsigned EltSize = S.Context.getTypeSize(EltType); + unsigned NumElts; + if (Info.ElementType == S.Context.BoolTy) { + NumElts = VecSize / S.Context.getCharWidth(); + VecKind = VectorKind::RVVFixedLengthMask; + } else { + ExpectedSize *= EltSize; + NumElts = VecSize / EltSize; + } + // The attribute vector size must match -mrvv-vector-bits. - unsigned ExpectedSize = VScale->first * MinElts * EltSize; - if (VecSize != ExpectedSize) { + if (ExpectedSize % 8 != 0 || VecSize != ExpectedSize) { S.Diag(Attr.getLoc(), diag::err_attribute_bad_rvv_vector_size) << VecSize << ExpectedSize; Attr.setInvalid(); return; } - VectorKind VecKind = VectorKind::RVVFixedLengthData; - VecSize /= EltSize; - CurType = S.Context.getVectorType(Info.ElementType, VecSize, VecKind); + CurType = S.Context.getVectorType(EltType, NumElts, VecKind); } /// Handle OpenCL Access Qualifier Attribute. diff --git a/clang/test/CodeGen/attr-riscv-rvv-vector-bits-bitcast.c b/clang/test/CodeGen/attr-riscv-rvv-vector-bits-bitcast.c index 886af083f1c009..b591249bbef1bc 100644 --- a/clang/test/CodeGen/attr-riscv-rvv-vector-bits-bitcast.c +++ b/clang/test/CodeGen/attr-riscv-rvv-vector-bits-bitcast.c @@ -18,8 +18,29 @@ typedef __rvv_uint64m1_t vuint64m1_t; typedef __rvv_float32m1_t vfloat32m1_t; typedef __rvv_float64m1_t vfloat64m1_t; +typedef __rvv_bool1_t vbool1_t; +typedef __rvv_bool2_t vbool2_t; +typedef __rvv_bool4_t vbool4_t; +typedef __rvv_bool8_t vbool8_t; +typedef __rvv_bool16_t vbool16_t; +typedef __rvv_bool32_t vbool32_t; +typedef __rvv_bool64_t vbool64_t; + typedef vint64m1_t fixed_int64m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); typedef vfloat64m1_t fixed_float64m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); +typedef vbool1_t fixed_bool1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen))); +typedef vbool2_t fixed_bool2_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 2))); +typedef vbool4_t fixed_bool4_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 4))); +typedef vbool8_t fixed_bool8_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 8))); +#if __riscv_v_fixed_vlen >= 128 +typedef vbool16_t fixed_bool16_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 16))); +#endif +#if __riscv_v_fixed_vlen >= 256 +typedef vbool32_t fixed_bool32_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 32))); +#endif +#if __riscv_v_fixed_vlen >= 512 +typedef vbool64_t fixed_bool64_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen / 64))); +#endif #define DEFINE_STRUCT(ty) \ struct struct_##ty { \ @@ -28,6 +49,19 @@ typedef vfloat64m1_t fixed_float64m1_t __attribute__((riscv_rvv_vector_bits(__ri DEFINE_STRUCT(int64m1) DEFINE_STRUCT(float64m1) +DEFINE_STRUCT(bool1) +DEFINE_STRUCT(bool2) +DEFINE_STRUCT(bool4) +DEFINE_STRUCT(bool8) +#if __riscv_v_fixed_vlen >= 128 +DEFINE_STRUCT(bool16) +#endif +#if __riscv_v_fixed_vlen >= 256 +DEFINE_STRUCT(bool32) +#endif +#if __riscv_v_fixed_vlen >= 512 +DEFINE_STRUCT(bool64) +#endif //===----------------------------------------------------------------------===// // int64 @@ -136,3 +170,69 @@ vfloat64m1_t read_float64m1(struct struct_float64m1 *s) { void write_float64m1(struct struct_float64m1 *s, vfloat64m1_t x) { s->y[0] = x; } + +//===----------------------------------------------------------------------===// +// bool +//===----------------------------------------------------------------------===// + +// CHECK-64-LABEL: @read_bool1( +// CHECK-64-NEXT: entry: +// CHECK-64-NEXT: [[SAVED_VALUE:%.*]] = alloca <8 x i8>, align 8 +// CHECK-64-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL1:%.*]], ptr [[S:%.*]], i64 0, i32 1 +// CHECK-64-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: store <8 x i8> [[TMP0]], ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: [[TMP1:%.*]] = load <vscale x 64 x i1>, ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: ret <vscale x 64 x i1> [[TMP1]] +// +// CHECK-128-LABEL: @read_bool1( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[SAVED_VALUE:%.*]] = alloca <16 x i8>, align 16 +// CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL1:%.*]], ptr [[S:%.*]], i64 0, i32 1 +// CHECK-128-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA4]] +// CHECK-128-NEXT: store <16 x i8> [[TMP0]], ptr [[SAVED_VALUE]], align 16, !tbaa [[TBAA4]] +// CHECK-128-NEXT: [[TMP1:%.*]] = load <vscale x 64 x i1>, ptr [[SAVED_VALUE]], align 16, !tbaa [[TBAA4]] +// CHECK-128-NEXT: ret <vscale x 64 x i1> [[TMP1]] +// +// CHECK-256-LABEL: @read_bool1( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[SAVED_VALUE:%.*]] = alloca <32 x i8>, align 32 +// CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL1:%.*]], ptr [[S:%.*]], i64 0, i32 1 +// CHECK-256-NEXT: [[TMP0:%.*]] = load <32 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA4]] +// CHECK-256-NEXT: store <32 x i8> [[TMP0]], ptr [[SAVED_VALUE]], align 32, !tbaa [[TBAA4]] +// CHECK-256-NEXT: [[TMP1:%.*]] = load <vscale x 64 x i1>, ptr [[SAVED_VALUE]], align 32, !tbaa [[TBAA4]] +// CHECK-256-NEXT: ret <vscale x 64 x i1> [[TMP1]] +// +vbool1_t read_bool1(struct struct_bool1 *s) { + return s->y[0]; +} + +// CHECK-64-LABEL: @write_bool1( +// CHECK-64-NEXT: entry: +// CHECK-64-NEXT: [[SAVED_VALUE:%.*]] = alloca <vscale x 64 x i1>, align 8 +// CHECK-64-NEXT: store <vscale x 64 x i1> [[X:%.*]], ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA7:![0-9]+]] +// CHECK-64-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL1:%.*]], ptr [[S:%.*]], i64 0, i32 1 +// CHECK-64-NEXT: store <8 x i8> [[TMP0]], ptr [[Y]], align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: ret void +// +// CHECK-128-LABEL: @write_bool1( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[SAVED_VALUE:%.*]] = alloca <vscale x 64 x i1>, align 16 +// CHECK-128-NEXT: store <vscale x 64 x i1> [[X:%.*]], ptr [[SAVED_VALUE]], align 16, !tbaa [[TBAA7:![0-9]+]] +// CHECK-128-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[SAVED_VALUE]], align 16, !tbaa [[TBAA4]] +// CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL1:%.*]], ptr [[S:%.*]], i64 0, i32 1 +// CHECK-128-NEXT: store <16 x i8> [[TMP0]], ptr [[Y]], align 8, !tbaa [[TBAA4]] +// CHECK-128-NEXT: ret void +// +// CHECK-256-LABEL: @write_bool1( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[SAVED_VALUE:%.*]] = alloca <vscale x 64 x i1>, align 8 +// CHECK-256-NEXT: store <vscale x 64 x i1> [[X:%.*]], ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA7:![0-9]+]] +// CHECK-256-NEXT: [[TMP0:%.*]] = load <32 x i8>, ptr [[SAVED_VALUE]], align 8, !tbaa [[TBAA4]] +// CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_STRUCT... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/76551 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits