[clang] [RISCV] Support __riscv_v_fixed_vlen for vbool types. (PR #76551)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 28 19:14:29 PST 2023
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
More information about the cfe-commits
mailing list