[llvm] fb4b133 - [ValueTracking] Treat RISC-V vsetvlimax as a power of two (#218831)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 21:19:01 PDT 2026


Author: Pengcheng Wang
Date: 2026-08-26T04:18:56Z
New Revision: fb4b133315e549394ab8d2df3e06f85fa9b3d6ff

URL: https://github.com/llvm/llvm-project/commit/fb4b133315e549394ab8d2df3e06f85fa9b3d6ff
DIFF: https://github.com/llvm/llvm-project/commit/fb4b133315e549394ab8d2df3e06f85fa9b3d6ff.diff

LOG: [ValueTracking] Treat RISC-V vsetvlimax as a power of two (#218831)

VLMAX = VLEN * LMUL / SEW is always a non-zero power of two for any valid
vtype, so llvm.riscv.vsetvlimax is a power of two regardless of SEW/LMUL or
whether a vscale_range is present. Report this in isKnownToBeAPowerOfTwo
so that consumers such as ctpop and the x & (x - 1) idiom can fold.

Assisted-by: TRAE CLI (Opus 4.8)

Added: 
    llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvlimax-ispow2.ll

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d4951ef705493..99f119868639e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2845,6 +2845,10 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, bool OrZero,
         if (II->getArgOperand(0) == II->getArgOperand(1))
           return isKnownToBeAPowerOfTwo(II->getArgOperand(0), OrZero, Q, Depth);
         break;
+      case Intrinsic::riscv_vsetvlimax:
+        // VLMAX is VLEN * LMUL / SEW, which is always a non-zero power of two
+        // for any valid vtype, so it is a power of two regardless of OrZero.
+        return true;
       default:
         break;
       }

diff  --git a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvlimax-ispow2.ll b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvlimax-ispow2.ll
new file mode 100644
index 0000000000000..9fb91f04eaa0e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvlimax-ispow2.ll
@@ -0,0 +1,63 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; VLMAX = VLEN * LMUL / SEW is always a non-zero power of two for any valid
+; vtype, so llvm.riscv.vsetvlimax is known to be a power of two irrespective of
+; SEW/LMUL or whether a vscale_range is present.
+
+; ctpop of a power of two is 1.
+define i64 @ctpop_e8m1_i64() #0 {
+; CHECK-LABEL: define i64 @ctpop_e8m1_i64(
+; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT:    ret i64 1
+;
+  %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 0)
+  %n = call i64 @llvm.ctpop.i64(i64 %vl)
+  ret i64 %n
+}
+
+; The result holds without a vscale_range too.
+define i64 @ctpop_e8m1_no_vscale_range_i64() {
+; CHECK-LABEL: define i64 @ctpop_e8m1_no_vscale_range_i64() {
+; CHECK-NEXT:    ret i64 1
+;
+  %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 0)
+  %n = call i64 @llvm.ctpop.i64(i64 %vl)
+  ret i64 %n
+}
+
+; A fractional LMUL with a large SEW (smallest VLMAX) is still a power of two.
+define i64 @ctpop_e64mf8_i64() {
+; CHECK-LABEL: define i64 @ctpop_e64mf8_i64() {
+; CHECK-NEXT:    ret i64 1
+;
+  %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 5)
+  %n = call i64 @llvm.ctpop.i64(i64 %vl)
+  ret i64 %n
+}
+
+; i32 result.
+define i32 @ctpop_e32mf2_i32() #0 {
+; CHECK-LABEL: define i32 @ctpop_e32mf2_i32(
+; CHECK-SAME: ) #[[ATTR2]] {
+; CHECK-NEXT:    ret i32 1
+;
+  %vl = call i32 @llvm.riscv.vsetvlimax.i32(i32 2, i32 7)
+  %n = call i32 @llvm.ctpop.i32(i32 %vl)
+  ret i32 %n
+}
+
+; The x & (x - 1) == 0 power-of-two idiom folds to true.
+define i1 @and_xminus1_is_zero_i64() #0 {
+; CHECK-LABEL: define i1 @and_xminus1_is_zero_i64(
+; CHECK-SAME: ) #[[ATTR2]] {
+; CHECK-NEXT:    ret i1 true
+;
+  %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 0)
+  %sub = sub i64 %vl, 1
+  %and = and i64 %vl, %sub
+  %cmp = icmp eq i64 %and, 0
+  ret i1 %cmp
+}
+
+attributes #0 = { vscale_range(2,1024) }


        


More information about the llvm-commits mailing list