[clang] [Clang][RISCV] Add assumptions to vsetvli/vsetvlimax (PR #79975)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 30 02:32:17 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-clang

Author: Wang Pengcheng (wangpc-pp)

<details>
<summary>Changes</summary>

There are some assumptions of the return value of vsetvli/vsetvlimax,
we add them via `llvm.assume` so that middle-end optimizations can
benefit from them.


---

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


6 Files Affected:

- (modified) clang/include/clang/Basic/riscv_vector.td (+97-3) 
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c (+575-44) 
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvlmax.c (+268-44) 
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsetvl.c (+575-44) 
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsetvlmax.c (+268-44) 
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/rvv-error.c (+8-2) 


``````````diff
diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td
index a00ca353588ed..84f61e3be4cfa 100644
--- a/clang/include/clang/Basic/riscv_vector.td
+++ b/clang/include/clang/Basic/riscv_vector.td
@@ -669,10 +669,104 @@ let HasBuiltinAlias = false,
     HasVL = false,
     HasMasked = false,
     MaskedPolicyScheme = NonePolicy,
-    Log2LMUL = [0],
-    ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type
-{
+    Log2LMUL = [0] in {
+
+  let ManualCodegen = [{
+    {
+      // Set XLEN type
+      IntrinsicTypes = {ResultType};
+      llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+      llvm::Value *VSetVL = Builder.CreateCall(F, Ops, "vl");
+
+      const TargetInfo &TI = getContext().getTargetInfo();
+      auto VScale = TI.getVScaleRange(getContext().getLangOpts());
+
+      if (VScale && VScale->first && VScale->first == VScale->second) {
+        // Assumptions:
+        //   Let:
+        //     fixed_vl = __riscv_v_fixed_vlen / 8;
+        //   We have:
+        //     (avl > fixed_vl || vl == avl)
+        //     and
+        //     (avl < fixed_vl * 2 || vl == fixed_vl)
+        Value *FixedVL = llvm::ConstantInt::get(ResultType, VScale->first * 8);
+        Value *FixedVLx2 =
+            llvm::ConstantInt::get(ResultType, VScale->first * 8 * 2);
+        Value *Cond0 = Builder.CreateICmpULE(
+            Ops[0], ConstantInt::get(ResultType, VScale->first * 8));
+
+        BasicBlock *AssumptionBlock =
+            createBasicBlock("assumption", this->CurFn);
+        BasicBlock *AssumptionEndBlock =
+            createBasicBlock("assumption_end", this->CurFn);
+        Builder.CreateCondBr(Cond0, AssumptionBlock, AssumptionEndBlock);
+
+        Builder.SetInsertPoint(AssumptionBlock);
+        Builder.CreateAssumption(Builder.CreateICmpEQ(VSetVL, Ops[0]));
+        Builder.CreateBr(AssumptionEndBlock);
+
+        Builder.SetInsertPoint(AssumptionEndBlock);
+        Value *Assumption0 = Builder.CreateICmpULT(Ops[0], FixedVLx2);
+        Value *Assumption1 = Builder.CreateICmpEQ(VSetVL, FixedVL);
+        Builder.CreateAssumption(Builder.CreateSelect(
+            Assumption0, ConstantInt::getTrue(getLLVMContext()), Assumption1));
+      } else {
+        // Assumptions:
+        //   Let:
+        //     min_vl = __riscv_v_min_vlen / 8
+        //   We have:
+        //     (avl > min_vl || vl == avl)
+        Value *Cond0 = Builder.CreateICmpULE(
+            Ops[0], ConstantInt::get(ResultType, VScale->first * 8));
+
+        BasicBlock *AssumptionBlock = createBasicBlock("assumption", this->CurFn);
+        BasicBlock *AssumptionEndBlock = createBasicBlock("assumption_end", this->CurFn);
+        Builder.CreateCondBr(Cond0, AssumptionBlock, AssumptionEndBlock);
+
+        Builder.SetInsertPoint(AssumptionBlock);
+        Value *Assumption = Builder.CreateICmpEQ(VSetVL, Ops[0]);
+        Builder.CreateAssumption(Assumption);
+        Builder.CreateBr(AssumptionEndBlock);
+
+        Builder.SetInsertPoint(AssumptionEndBlock);
+      }
+      return VSetVL;
+    }
+    }] in
   def vsetvli : RVVBuiltin<"", "zzKzKz", "i">;
+
+  let ManualCodegen = [{
+    {
+      // Set XLEN type
+      IntrinsicTypes = {ResultType};
+      llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+      llvm::Value *VSetVL = Builder.CreateCall(F, Ops, "vl");
+
+      const TargetInfo &TI = getContext().getTargetInfo();
+      auto VScale = TI.getVScaleRange(getContext().getLangOpts());
+
+      Value *Assumption;
+      if (VScale && VScale->first && VScale->first == VScale->second)
+        // Assumptions:
+        //   Let:
+        //     fixed_vl = __riscv_v_fixed_vlen / 8;
+        //   We have:
+        //     vlmax == fixed_vl
+        Assumption = Builder.CreateICmpEQ(
+            VSetVL, llvm::ConstantInt::get(ResultType, VScale->first * 8));
+      else
+        // Assumptions:
+        //   Let:
+        //     min_vl = __riscv_v_min_vlen / 8
+        //   We have:
+        //     vlmax >= min_vl
+        Assumption = Builder.CreateICmpUGE(
+            VSetVL, ConstantInt::get(ResultType, VScale->first * 8));
+
+      Builder.CreateAssumption(Assumption);
+      return VSetVL;
+    }
+    }] in
   def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">;
 }
 
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c
index 26d2e0a4868d5..42f465e33f6fd 100644
--- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c
@@ -3,14 +3,41 @@
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -disable-O0-optnone \
 // RUN:   -emit-llvm %s -o - | opt -S -passes=mem2reg | \
 // RUN:   FileCheck --check-prefix=CHECK-RV64 %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -disable-O0-optnone \
+// RUN:   -mvscale-min=2 -mvscale-max=2 -emit-llvm %s -o - | opt -S -passes=mem2reg | \
+// RUN:   FileCheck --check-prefix=CHECK-RV64-FIXED %s
 
 #include <riscv_vector.h>
 
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8mf8
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 5)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 5)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8mf8
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 5)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8mf8(size_t avl) {
   return __riscv_vsetvl_e8mf8(avl);
@@ -19,8 +46,32 @@ size_t test_vsetvl_e8mf8(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8mf4
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 6)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 6)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8mf4
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 6)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8mf4(size_t avl) {
   return __riscv_vsetvl_e8mf4(avl);
@@ -29,8 +80,32 @@ size_t test_vsetvl_e8mf4(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8mf2
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 7)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 7)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8mf2
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 7)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8mf2(size_t avl) {
   return __riscv_vsetvl_e8mf2(avl);
@@ -39,8 +114,32 @@ size_t test_vsetvl_e8mf2(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8m1
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8m1
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8m1(size_t avl) {
   return __riscv_vsetvl_e8m1(avl);
@@ -49,8 +148,32 @@ size_t test_vsetvl_e8m1(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8m2
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 1)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 1)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8m2
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 1)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8m2(size_t avl) {
   return __riscv_vsetvl_e8m2(avl);
@@ -59,8 +182,32 @@ size_t test_vsetvl_e8m2(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8m4
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 2)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 2)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8m4
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 2)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8m4(size_t avl) {
   return __riscv_vsetvl_e8m4(avl);
@@ -69,8 +216,32 @@ size_t test_vsetvl_e8m4(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e8m8
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 3)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 3)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e8m8
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK-RV64-FIXED-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 3)
+// CHECK-RV64-FIXED-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-FIXED-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64-FIXED:       assumption:
+// CHECK-RV64-FIXED-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-FIXED-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64-FIXED:       assumption_end:
+// CHECK-RV64-FIXED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[AVL]], 32
+// CHECK-RV64-FIXED-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[VL]], 16
+// CHECK-RV64-FIXED-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i1 true, i1 [[TMP3]]
+// CHECK-RV64-FIXED-NEXT:    call void @llvm.assume(i1 [[TMP4]])
+// CHECK-RV64-FIXED-NEXT:    ret i64 [[VL]]
 //
 size_t test_vsetvl_e8m8(size_t avl) {
   return __riscv_vsetvl_e8m8(avl);
@@ -79,8 +250,32 @@ size_t test_vsetvl_e8m8(size_t avl) {
 // CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16mf4
 // CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 6)
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+// CHECK-RV64-NEXT:    [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 6)
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = icmp ule i64 [[AVL]], 16
+// CHECK-RV64-NEXT:    br i1 [[TMP0]], label [[ASSUMPTION:%.*]], label [[ASSUMPTION_END:%.*]]
+// CHECK-RV64:       assumption:
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+// CHECK-RV64-NEXT:    br label [[ASSUMPTION_END]]
+// CHECK-RV64:       assumption_end:
+// CHECK-RV64-NEXT:    ret i64 [[VL]]
+//
+// CHECK-RV64-FIXED-LABEL: define dso_local i64 @test_vsetvl_e16mf4
+// CHECK-RV64-FIXED-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-FIXED-NEXT:  entry:
+// CHECK...
[truncated]

``````````

</details>


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


More information about the cfe-commits mailing list