[clang] [Clang][RISCV] Add assumptions for vsetvli and vsetvlimax results (PR #218311)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 23 21:00:18 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
@llvm/pr-subscribers-clang-codegen
Author: Pengcheng Wang (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.
Fixes #<!-- -->217784.
---
Patch is 68.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218311.diff
6 Files Affected:
- (modified) clang/lib/CodeGen/TargetBuiltins/RISCV.cpp (+49-1)
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvl.c (+132-44)
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsetvlmax.c (+88-44)
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsetvl.c (+132-44)
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsetvlmax.c (+88-44)
- (modified) clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/rvv-error.c (+5-2)
``````````diff
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index 88fedecbee504..0121957d73061 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -305,7 +305,55 @@ emitRVVVsetvliBuiltin(CodeGenFunction *CGF, const CallExpr *E,
auto &Builder = CGF->Builder;
auto &CGM = CGF->CGM;
llvm::Function *F = CGM.getIntrinsic(ID, {ResultType});
- return Builder.CreateCall(F, Ops, "");
+ llvm::Value *VSetVL = Builder.CreateCall(F, Ops, "vl");
+
+ bool HasAVL = ID == llvm::Intrinsic::riscv_vsetvli;
+ assert((HasAVL || ID == llvm::Intrinsic::riscv_vsetvlimax) &&
+ "Unexpected vsetvl intrinsic");
+
+ unsigned SEW = llvm::RISCVVType::decodeVSEW(
+ cast<ConstantInt>(Ops[HasAVL])->getZExtValue());
+ auto VLMUL = static_cast<llvm::RISCVVType::VLMUL>(
+ cast<ConstantInt>(Ops[HasAVL + 1])->getZExtValue());
+ unsigned Ratio = llvm::RISCVVType::getSEWLMULRatio(SEW, VLMUL);
+
+ Attribute VScaleRange =
+ CGF->CurFn->getFnAttribute(llvm::Attribute::VScaleRange);
+ if (!VScaleRange.isValid())
+ return VSetVL;
+
+ uint64_t MinVLMAX = uint64_t(VScaleRange.getVScaleRangeMin()) *
+ llvm::RISCV::RVVBitsPerBlock / Ratio;
+ std::optional<unsigned> MaxVScale = VScaleRange.getVScaleRangeMax();
+
+ if (!HasAVL) {
+ Value *Assumption;
+ if (MaxVScale && *MaxVScale == VScaleRange.getVScaleRangeMin())
+ Assumption = Builder.CreateICmpEQ(
+ VSetVL, llvm::ConstantInt::get(ResultType, MinVLMAX));
+ else
+ Assumption = Builder.CreateICmpUGE(
+ VSetVL, llvm::ConstantInt::get(ResultType, MinVLMAX));
+ Builder.CreateAssumption(Assumption);
+ return VSetVL;
+ }
+
+ Value *AVLAboveMinVLMAX = Builder.CreateICmpUGT(
+ Ops[0], llvm::ConstantInt::get(ResultType, MinVLMAX));
+ Value *VLEqualsAVL = Builder.CreateICmpEQ(VSetVL, Ops[0]);
+ Builder.CreateAssumption(
+ Builder.CreateSelect(AVLAboveMinVLMAX, Builder.getTrue(), VLEqualsAVL));
+
+ if (MaxVScale && *MaxVScale == VScaleRange.getVScaleRangeMin()) {
+ uint64_t FixedVLMAX = MinVLMAX;
+ Value *AVLBelowTwiceVLMAX = Builder.CreateICmpULT(
+ Ops[0], llvm::ConstantInt::get(ResultType, FixedVLMAX * 2));
+ Value *VLEqualsVLMAX = Builder.CreateICmpEQ(
+ VSetVL, llvm::ConstantInt::get(ResultType, FixedVLMAX));
+ Builder.CreateAssumption(Builder.CreateSelect(
+ AVLBelowTwiceVLMAX, Builder.getTrue(), VLEqualsVLMAX));
+ }
+ return VSetVL;
}
static LLVM_ATTRIBUTE_NOINLINE Value *
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..c815f1a7620fe 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
@@ -9,8 +9,12 @@
// 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 ugt i64 [[AVL]], 2
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8mf8(size_t avl) {
return __riscv_vsetvl_e8mf8(avl);
@@ -19,8 +23,12 @@ 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 ugt i64 [[AVL]], 4
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8mf4(size_t avl) {
return __riscv_vsetvl_e8mf4(avl);
@@ -29,8 +37,12 @@ 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 ugt i64 [[AVL]], 8
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8mf2(size_t avl) {
return __riscv_vsetvl_e8mf2(avl);
@@ -39,8 +51,12 @@ 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 ugt i64 [[AVL]], 16
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8m1(size_t avl) {
return __riscv_vsetvl_e8m1(avl);
@@ -49,8 +65,12 @@ 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 ugt i64 [[AVL]], 32
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8m2(size_t avl) {
return __riscv_vsetvl_e8m2(avl);
@@ -59,8 +79,12 @@ 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 ugt i64 [[AVL]], 64
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8m4(size_t avl) {
return __riscv_vsetvl_e8m4(avl);
@@ -69,8 +93,12 @@ 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 ugt i64 [[AVL]], 128
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e8m8(size_t avl) {
return __riscv_vsetvl_e8m8(avl);
@@ -79,8 +107,12 @@ 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 ugt i64 [[AVL]], 2
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16mf4(size_t avl) {
return __riscv_vsetvl_e16mf4(avl);
@@ -89,8 +121,12 @@ size_t test_vsetvl_e16mf4(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16mf2
// 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 7)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 7)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 4
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16mf2(size_t avl) {
return __riscv_vsetvl_e16mf2(avl);
@@ -99,8 +135,12 @@ size_t test_vsetvl_e16mf2(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16m1
// 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 0)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 0)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 8
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16m1(size_t avl) {
return __riscv_vsetvl_e16m1(avl);
@@ -109,8 +149,12 @@ size_t test_vsetvl_e16m1(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16m2
// 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 1)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 1)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 16
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16m2(size_t avl) {
return __riscv_vsetvl_e16m2(avl);
@@ -119,8 +163,12 @@ size_t test_vsetvl_e16m2(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16m4
// 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 2)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 2)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 32
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16m4(size_t avl) {
return __riscv_vsetvl_e16m4(avl);
@@ -129,8 +177,12 @@ size_t test_vsetvl_e16m4(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e16m8
// 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 3)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 1, i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 64
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e16m8(size_t avl) {
return __riscv_vsetvl_e16m8(avl);
@@ -139,8 +191,12 @@ size_t test_vsetvl_e16m8(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e32mf2
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 7)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 7)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 2
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e32mf2(size_t avl) {
return __riscv_vsetvl_e32mf2(avl);
@@ -149,8 +205,12 @@ size_t test_vsetvl_e32mf2(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e32m1
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 0)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 0)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 4
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e32m1(size_t avl) {
return __riscv_vsetvl_e32m1(avl);
@@ -159,8 +219,12 @@ size_t test_vsetvl_e32m1(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e32m2
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 1)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 1)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 8
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e32m2(size_t avl) {
return __riscv_vsetvl_e32m2(avl);
@@ -169,8 +233,12 @@ size_t test_vsetvl_e32m2(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e32m4
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 2)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 2)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 16
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e32m4(size_t avl) {
return __riscv_vsetvl_e32m4(avl);
@@ -179,8 +247,12 @@ size_t test_vsetvl_e32m4(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e32m8
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 3)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 2, i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 32
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e32m8(size_t avl) {
return __riscv_vsetvl_e32m8(avl);
@@ -189,8 +261,12 @@ size_t test_vsetvl_e32m8(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e64m1
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 0)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 0)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 2
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e64m1(size_t avl) {
return __riscv_vsetvl_e64m1(avl);
@@ -199,8 +275,12 @@ size_t test_vsetvl_e64m1(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e64m2
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 1)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 1)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 4
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t test_vsetvl_e64m2(size_t avl) {
return __riscv_vsetvl_e64m2(avl);
@@ -209,8 +289,12 @@ size_t test_vsetvl_e64m2(size_t avl) {
// CHECK-RV64-LABEL: define dso_local i64 @test_vsetvl_e64m4
// CHECK-RV64-SAME: (i64 noundef [[AVL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 2)
-// CHECK-RV64-NEXT: ret i64 [[TMP0]]
+// CHECK-RV64-NEXT: [[VL:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 3, i64 2)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[AVL]], 8
+// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i64 [[VL]], [[AVL]]
+// CHECK-RV64-NEXT: [[TMP2:%.*]] = select i1 [[TMP0]], i1 true, i1 [[TMP1]]
+// CHECK-RV64-NEXT: call void @llvm.assume(i1 [[TMP2]])
+// CHECK-RV64-NEXT: ret i64 [[VL]]
//
size_t ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/218311
More information about the cfe-commits
mailing list