[clang] [RISCV] full support for riscv_rvv_vector_bits attribute (PR #100110)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 23 04:53:52 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vladislav Belov (vbe-sc)

<details>
<summary>Changes</summary>

Add support for using attribute((rvv_vector_bits(N))), when N < 8.
It allows using all fixed length vector mask types regardless VLEN value.

---

Patch is 400.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/100110.diff


16 Files Affected:

- (modified) clang/include/clang/AST/Type.h (+4) 
- (modified) clang/lib/AST/ASTContext.cpp (+32-4) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+8-2) 
- (modified) clang/lib/AST/JSONNodeDumper.cpp (+3) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (+3) 
- (modified) clang/lib/AST/TypePrinter.cpp (+6) 
- (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+8-2) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+11-2) 
- (modified) clang/lib/Sema/SemaType.cpp (+16-2) 
- (added) clang/test/CodeGen/RISCV/attr-riscv-rvv-vector-bits-less-8-call.c (+220) 
- (added) clang/test/CodeGen/RISCV/attr-riscv-rvv-vector-bits-less-8-cast.c (+98) 
- (added) clang/test/CodeGen/RISCV/attr-rvv-vector-bits-bitcast-less-8.c (+106) 
- (modified) clang/test/CodeGen/RISCV/attr-rvv-vector-bits-globals.c (+18-18) 
- (modified) clang/test/CodeGen/RISCV/attr-rvv-vector-bits-types.c (+574-1464) 
- (modified) clang/test/CodeGenCXX/riscv-mangle-rvv-fixed-vectors.cpp (+2970-336) 
- (modified) clang/test/Sema/attr-riscv-rvv-vector-bits.c (+6-12) 


``````````diff
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 25defea58c2dc..a9a87ac5837f1 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3981,6 +3981,10 @@ enum class VectorKind {
 
   /// is RISC-V RVV fixed-length mask vector
   RVVFixedLengthMask,
+
+  RVVFixedLengthMask_1,
+  RVVFixedLengthMask_2,
+  RVVFixedLengthMask_4
 };
 
 /// Represents a GCC generic vector type. This type is created using
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7af9ea7105bb0..7febe4d39067d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1983,7 +1983,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
       // Adjust the alignment for fixed-length SVE predicates.
       Align = 16;
     else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
-             VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
+             VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+             VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+             VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+             VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
       // Adjust the alignment for fixed-length RVV vectors.
       Align = std::min<unsigned>(64, Width);
     break;
@@ -9896,7 +9899,13 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
       First->getVectorKind() != VectorKind::RVVFixedLengthData &&
       Second->getVectorKind() != VectorKind::RVVFixedLengthData &&
       First->getVectorKind() != VectorKind::RVVFixedLengthMask &&
-      Second->getVectorKind() != VectorKind::RVVFixedLengthMask)
+      Second->getVectorKind() != VectorKind::RVVFixedLengthMask &&
+      First->getVectorKind() != VectorKind::RVVFixedLengthMask_1 &&
+      Second->getVectorKind() != VectorKind::RVVFixedLengthMask_1 &&
+      First->getVectorKind() != VectorKind::RVVFixedLengthMask_2 &&
+      Second->getVectorKind() != VectorKind::RVVFixedLengthMask_2 &&
+      First->getVectorKind() != VectorKind::RVVFixedLengthMask_4 &&
+      Second->getVectorKind() != VectorKind::RVVFixedLengthMask_4)
     return true;
 
   return false;
@@ -10014,14 +10023,33 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType,
           BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
           return FirstType->isRVVVLSBuiltinType() &&
                  Info.ElementType == BoolTy &&
-                 getTypeSize(SecondType) == getRVVTypeSize(*this, BT);
+                 getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)));
+        }
+        if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1) {
+          BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
+          return FirstType->isRVVVLSBuiltinType() &&
+                 Info.ElementType == BoolTy &&
+                 getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT) * 8));
+        }
+        if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2) {
+          BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
+          return FirstType->isRVVVLSBuiltinType() &&
+                 Info.ElementType == BoolTy &&
+                 getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 4);
+        }
+        if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) {
+          BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
+          return FirstType->isRVVVLSBuiltinType() &&
+                 Info.ElementType == BoolTy &&
+                 getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 2);
         }
         if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
-            VT->getVectorKind() == VectorKind::Generic)
+            VT->getVectorKind() == VectorKind::Generic) {
           return FirstType->isRVVVLSBuiltinType() &&
                  getTypeSize(SecondType) == getRVVTypeSize(*this, BT) &&
                  hasSameType(VT->getElementType(),
                              getBuiltinVectorTypeInfo(BT).ElementType);
+        }
       }
     }
     return false;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 40ef82785f454..d6e5681042892 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4005,7 +4005,10 @@ void CXXNameMangler::mangleAArch64FixedSveVectorType(
 
 void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) {
   assert((T->getVectorKind() == VectorKind::RVVFixedLengthData ||
-          T->getVectorKind() == VectorKind::RVVFixedLengthMask) &&
+          T->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+          T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+          T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+          T->getVectorKind() == VectorKind::RVVFixedLengthMask_4) &&
          "expected fixed-length RVV vector!");
 
   QualType EltType = T->getElementType();
@@ -4112,7 +4115,10 @@ void CXXNameMangler::mangleType(const VectorType *T) {
     mangleAArch64FixedSveVectorType(T);
     return;
   } else if (T->getVectorKind() == VectorKind::RVVFixedLengthData ||
-             T->getVectorKind() == VectorKind::RVVFixedLengthMask) {
+             T->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+             T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+             T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+             T->getVectorKind() == VectorKind::RVVFixedLengthMask_4) {
     mangleRISCVFixedRVVVectorType(T);
     return;
   }
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index eeb314b8d32b0..f8f80c8c25157 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -737,6 +737,9 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) {
     JOS.attribute("vectorKind", "fixed-length rvv data vector");
     break;
   case VectorKind::RVVFixedLengthMask:
+  case VectorKind::RVVFixedLengthMask_1:
+  case VectorKind::RVVFixedLengthMask_2:
+  case VectorKind::RVVFixedLengthMask_4:
     JOS.attribute("vectorKind", "fixed-length rvv mask vector");
     break;
   }
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 5ba9523504258..388c927c9aa55 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1859,6 +1859,9 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) {
     OS << " fixed-length rvv data vector";
     break;
   case VectorKind::RVVFixedLengthMask:
+  case VectorKind::RVVFixedLengthMask_1:
+  case VectorKind::RVVFixedLengthMask_2:
+  case VectorKind::RVVFixedLengthMask_4:
     OS << " fixed-length rvv mask vector";
     break;
   }
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ffec3ef9d2269..f9bf63aa86e73 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -721,6 +721,9 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
     break;
   case VectorKind::RVVFixedLengthData:
   case VectorKind::RVVFixedLengthMask:
+  case VectorKind::RVVFixedLengthMask_1:
+  case VectorKind::RVVFixedLengthMask_2:
+  case VectorKind::RVVFixedLengthMask_4:
     // 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__(";
@@ -801,6 +804,9 @@ void TypePrinter::printDependentVectorBefore(
     break;
   case VectorKind::RVVFixedLengthData:
   case VectorKind::RVVFixedLengthMask:
+  case VectorKind::RVVFixedLengthMask_1:
+  case VectorKind::RVVFixedLengthMask_2:
+  case VectorKind::RVVFixedLengthMask_4:
     // 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 f2add9351c03c..9f0766aa357fc 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -328,7 +328,10 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const {
 
   unsigned NumElts = VT->getNumElements();
   llvm::Type *EltType;
-  if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) {
+  if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+      VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+      VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+      VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) {
     NumElts *= 8;
     EltType = llvm::Type::getInt1Ty(getVMContext());
   } else {
@@ -453,7 +456,10 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
 
   if (const VectorType *VT = Ty->getAs<VectorType>())
     if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
-        VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
+        VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+        VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+        VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+        VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
       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 439db55668cc6..d8156f68205eb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10115,7 +10115,10 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
           VecType->getVectorKind() == VectorKind::SveFixedLengthPredicate)
         return true;
       if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData ||
-          VecType->getVectorKind() == VectorKind::RVVFixedLengthMask) {
+          VecType->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+          VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
+          VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
+          VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_4) {
         SVEorRVV = 1;
         return true;
       }
@@ -10147,7 +10150,13 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                 VectorKind::SveFixedLengthPredicate)
           return true;
         if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData ||
-            SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask) {
+            SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask ||
+            SecondVecType->getVectorKind() ==
+                VectorKind::RVVFixedLengthMask_1 ||
+            SecondVecType->getVectorKind() ==
+                VectorKind::RVVFixedLengthMask_2 ||
+            SecondVecType->getVectorKind() ==
+                VectorKind::RVVFixedLengthMask_4) {
           SVEorRVV = 1;
           return true;
         }
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 6fa39cdccef2b..6c87792b382f8 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8349,14 +8349,28 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType,
   unsigned NumElts;
   if (Info.ElementType == S.Context.BoolTy) {
     NumElts = VecSize / S.Context.getCharWidth();
-    VecKind = VectorKind::RVVFixedLengthMask;
+    if (!NumElts) {
+      NumElts = 1;
+      switch (VecSize) {
+      case 1:
+        VecKind = VectorKind::RVVFixedLengthMask_1;
+        break;
+      case 2:
+        VecKind = VectorKind::RVVFixedLengthMask_2;
+        break;
+      case 4:
+        VecKind = VectorKind::RVVFixedLengthMask_4;
+        break;
+      }
+    } else
+      VecKind = VectorKind::RVVFixedLengthMask;
   } else {
     ExpectedSize *= EltSize;
     NumElts = VecSize / EltSize;
   }
 
   // The attribute vector size must match -mrvv-vector-bits.
-  if (ExpectedSize % 8 != 0 || VecSize != ExpectedSize) {
+  if (VecSize != ExpectedSize) {
     S.Diag(Attr.getLoc(), diag::err_attribute_bad_rvv_vector_size)
         << VecSize << ExpectedSize;
     Attr.setInvalid();
diff --git a/clang/test/CodeGen/RISCV/attr-riscv-rvv-vector-bits-less-8-call.c b/clang/test/CodeGen/RISCV/attr-riscv-rvv-vector-bits-less-8-call.c
new file mode 100644
index 0000000000000..991c145393602
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/attr-riscv-rvv-vector-bits-less-8-call.c
@@ -0,0 +1,220 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=1 -mvscale-max=1 -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-64
+// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=2 -mvscale-max=2 -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128
+
+// REQUIRES: riscv-registered-target
+
+#include <riscv_vector.h>
+
+typedef vbool32_t fixed_bool32_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen/32)));
+typedef vbool64_t fixed_bool64_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen/64)));
+
+//===----------------------------------------------------------------------===//
+// fixed, fixed
+//===----------------------------------------------------------------------===//
+
+// CHECK-64-LABEL: @call_bool32_ff(
+// CHECK-64-NEXT:  entry:
+// CHECK-64-NEXT:    [[SAVED_VALUE:%.*]] = alloca <1 x i8>, align 1
+// CHECK-64-NEXT:    [[SAVED_VALUE2:%.*]] = alloca <1 x i8>, align 1
+// CHECK-64-NEXT:    [[SAVED_VALUE3:%.*]] = alloca <vscale x 2 x i1>, align 1
+// CHECK-64-NEXT:    [[OP1_COERCE:%.*]] = bitcast <vscale x 8 x i1> [[TMP0:%.*]] to <vscale x 1 x i8>
+// CHECK-64-NEXT:    [[OP1:%.*]] = tail call <1 x i8> @llvm.vector.extract.v1i8.nxv1i8(<vscale x 1 x i8> [[OP1_COERCE]], i64 0)
+// CHECK-64-NEXT:    [[OP2_COERCE:%.*]] = bitcast <vscale x 8 x i1> [[TMP1:%.*]] to <vscale x 1 x i8>
+// CHECK-64-NEXT:    [[OP2:%.*]] = tail call <1 x i8> @llvm.vector.extract.v1i8.nxv1i8(<vscale x 1 x i8> [[OP2_COERCE]], i64 0)
+// CHECK-64-NEXT:    store <1 x i8> [[OP1]], ptr [[SAVED_VALUE]], align 1, !tbaa [[TBAA6:![0-9]+]]
+// CHECK-64-NEXT:    [[TMP2:%.*]] = load <vscale x 2 x i1>, ptr [[SAVED_VALUE]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    store <1 x i8> [[OP2]], ptr [[SAVED_VALUE2]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[TMP3:%.*]] = load <vscale x 2 x i1>, ptr [[SAVED_VALUE2]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[TMP4:%.*]] = tail call <vscale x 2 x i1> @llvm.riscv.vmand.nxv2i1.i64(<vscale x 2 x i1> [[TMP2]], <vscale x 2 x i1> [[TMP3]], i64 2)
+// CHECK-64-NEXT:    store <vscale x 2 x i1> [[TMP4]], ptr [[SAVED_VALUE3]], align 1, !tbaa [[TBAA9:![0-9]+]]
+// CHECK-64-NEXT:    [[TMP5:%.*]] = load <1 x i8>, ptr [[SAVED_VALUE3]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 1 x i8> @llvm.vector.insert.nxv1i8.v1i8(<vscale x 1 x i8> undef, <1 x i8> [[TMP5]], i64 0)
+// CHECK-64-NEXT:    [[TMP6:%.*]] = bitcast <vscale x 1 x i8> [[CAST_SCALABLE]] to <vscale x 8 x i1>
+// CHECK-64-NEXT:    ret <vscale x 8 x i1> [[TMP6]]
+//
+// CHECK-128-LABEL: @call_bool32_ff(
+// CHECK-128-NEXT:  entry:
+// CHECK-128-NEXT:    [[OP1:%.*]] = alloca <1 x i8>, align 1
+// CHECK-128-NEXT:    [[OP2:%.*]] = alloca <1 x i8>, align 1
+// CHECK-128-NEXT:    [[SAVED_VALUE4:%.*]] = alloca <vscale x 2 x i1>, align 1
+// CHECK-128-NEXT:    [[RETVAL_COERCE:%.*]] = alloca <vscale x 4 x i1>, align 1
+// CHECK-128-NEXT:    store <vscale x 4 x i1> [[OP1_COERCE:%.*]], ptr [[OP1]], align 1
+// CHECK-128-NEXT:    store <vscale x 4 x i1> [[OP2_COERCE:%.*]], ptr [[OP2]], align 1
+// CHECK-128-NEXT:    [[TMP0:%.*]] = load <vscale x 2 x i1>, ptr [[OP1]], align 1, !tbaa [[TBAA6:![0-9]+]]
+// CHECK-128-NEXT:    [[TMP1:%.*]] = load <vscale x 2 x i1>, ptr [[OP2]], align 1, !tbaa [[TBAA6]]
+// CHECK-128-NEXT:    [[TMP2:%.*]] = tail call <vscale x 2 x i1> @llvm.riscv.vmand.nxv2i1.i64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x i1> [[TMP1]], i64 4)
+// CHECK-128-NEXT:    store <vscale x 2 x i1> [[TMP2]], ptr [[SAVED_VALUE4]], align 1, !tbaa [[TBAA9:![0-9]+]]
+// CHECK-128-NEXT:    [[TMP3:%.*]] = load <1 x i8>, ptr [[SAVED_VALUE4]], align 1, !tbaa [[TBAA6]]
+// CHECK-128-NEXT:    store <1 x i8> [[TMP3]], ptr [[RETVAL_COERCE]], align 1
+// CHECK-128-NEXT:    [[TMP4:%.*]] = load <vscale x 4 x i1>, ptr [[RETVAL_COERCE]], align 1
+// CHECK-128-NEXT:    ret <vscale x 4 x i1> [[TMP4]]
+//
+fixed_bool32_t call_bool32_ff(fixed_bool32_t op1, fixed_bool32_t op2) {
+  return __riscv_vmand(op1, op2, __riscv_v_fixed_vlen / 32);
+}
+
+// CHECK-64-LABEL: @call_bool64_ff(
+// CHECK-64-NEXT:  entry:
+// CHECK-64-NEXT:    [[SAVED_VALUE:%.*]] = alloca <1 x i8>, align 1
+// CHECK-64-NEXT:    [[SAVED_VALUE2:%.*]] = alloca <1 x i8>, align 1
+// CHECK-64-NEXT:    [[SAVED_VALUE3:%.*]] = alloca <vscale x 1 x i1>, align 1
+// CHECK-64-NEXT:    [[OP1_COERCE:%.*]] = bitcast <vscale x 8 x i1> [[TMP0:%.*]] to <vscale x 1 x i8>
+// CHECK-64-NEXT:    [[OP1:%.*]] = tail call <1 x i8> @llvm.vector.extract.v1i8.nxv1i8(<vscale x 1 x i8> [[OP1_COERCE]], i64 0)
+// CHECK-64-NEXT:    [[OP2_COERCE:%.*]] = bitcast <vscale x 8 x i1> [[TMP1:%.*]] to <vscale x 1 x i8>
+// CHECK-64-NEXT:    [[OP2:%.*]] = tail call <1 x i8> @llvm.vector.extract.v1i8.nxv1i8(<vscale x 1 x i8> [[OP2_COERCE]], i64 0)
+// CHECK-64-NEXT:    store <1 x i8> [[OP1]], ptr [[SAVED_VALUE]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[TMP2:%.*]] = load <vscale x 1 x i1>, ptr [[SAVED_VALUE]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    store <1 x i8> [[OP2]], ptr [[SAVED_VALUE2]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[TMP3:%.*]] = load <vscale x 1 x i1>, ptr [[SAVED_VALUE2]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[TMP4:%.*]] = tail call <vscale x 1 x i1> @llvm.riscv.vmand.nxv1i1.i64(<vscale x 1 x i1> [[TMP2]], <vscale x 1 x i1> [[TMP3]], i64 1)
+// CHECK-64-NEXT:    store <vscale x 1 x i1> [[TMP4]], ptr [[SAVED_VALUE3]], align 1, !tbaa [[TBAA11:![0-9]+]]
+// CHECK-64-NEXT:    [[TMP5:%.*]] = load <1 x i8>, ptr [[SAVED_VALUE3]], align 1, !tbaa [[TBAA6]]
+// CHECK-64-NEXT:    [[CAST_SCALABLE:%.*]] = tail call <vscale x 1 x i8> @llvm.vector.insert.nxv1i8.v1i8(<vscale x 1 x i8> undef, <1 x i8> [[TMP5]], i64 0)
+// CHECK-64-NEXT:    [[TMP6:%.*]] = bitcast <vscale x 1 x i8> [[CAST_SCALABLE]] to <vscale x 8 x i1>
+// CHECK-64-NEXT:    ret <vscale x 8 x i1> [[TMP6]]
+//
+// CHECK-128-LABEL: @call_bool64_ff(
+// CHECK-128-NEXT:  entry:
+// CHECK-128-NEXT:    [[OP1:%.*]] = alloca <1 x i8>, align 1
+// CHECK-128-NEXT:    [[OP2:%.*]] = alloca <1 x i8>, align 1
+// CHECK-128-NEXT:    [[SAVED_VALUE4:%.*]] = alloca <vscale x 1 x i1>, align 1
+// CHECK-128-NEXT:    [[RETVAL_COERCE:%.*]] = alloca <vscale x 4 x i1>, align 1
+// CHECK-128-NEXT:    store <vscale x 4 x i1> [[OP1_COERCE:%.*]], ptr [[OP1]], align 1
+// CHECK-128-NEXT:    store <vscale x 4 x i1> [[OP2_COERCE:%.*]], ptr [[OP2]], align 1
+// CHECK-128-NEXT:    [[TMP0:%.*]] = load <vscale x 1 x i1>, ptr [[OP1]], align 1, !tbaa [[TBAA6]]
+// CHECK-128-NEXT:    [[TMP1:%.*]] = load <vscale x 1 x i1>, ptr [[OP2]], align 1, !tbaa [[TBAA6]]
+// CHECK-128-NEXT:    [[TMP2:%.*]] = tail call <vscale x 1 x i1> @llvm.riscv.vmand.nxv1i1.i64(<vscale x 1 x i1> [[TMP0]], <vscale x 1 x i1> [[TMP1]], i64 2)
+// CHECK-128-NEXT:    store <vscale x 1 x i1> [[TMP2]], ptr [[SAVED_VALUE4]], align 1, !tbaa [[TBAA11:![0-9]+]]
+// CHECK-128-NEXT:    [[TMP3:%.*]] = load <1 x i8>, ptr [[SAVED_VALUE4]], align 1, !tbaa [[TBAA6]]
+// CHECK-128-NEXT:    store <1 x i8> [[TMP3]], ptr [[RETVAL_COERCE]], align 1
+// CHECK-128-NEXT:    [[TMP4:%.*]] = load <vscale x 4 x i1>, ptr [[RETVAL_COERCE]], align 1
+// CHECK-128-NEXT:    ret <vscale x 4 x i1> [[TMP4]]
+//
+fixed_bool64_t call_bool64_ff(fixed_bool64_t op1, fixed_bool64_t op2) {
+  return __riscv_vmand(op1, op2, __riscv_v_fixed_vlen / 64);
+}
+
+//===----------------------------------------------------------------------===//
+// fixed, scalable
+//===----------------------------------------------------------------------===//
+
+// CHECK-64-LABEL: @call_bool32_fs(
+// CHECK-64-NEXT:  entry:
+// CHECK-64-NEXT:    [[SAVED_VALUE:%.*]] = alloca <1 x i8>, align 1
+// CHECK-64-NEXT:    [[SAVED_VALUE1:%.*]] = alloca <vscale x 2 x i1>, align 1
+// CHECK-64-NEXT:    [[OP1_COERCE:%.*]...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/100110


More information about the cfe-commits mailing list