https://github.com/wangpc-pp created
https://github.com/llvm/llvm-project/pull/219924
`__riscv_vlenb()` reads the `vlenb` CSR, which holds `VLEN/8`.
In this PR, we attach a range return attribute to the emitted
`read_register("vlenb")` call, derived from the target's VLEN
bounds via `TargetInfo::getVScaleRange()`:
VLENB = VScale * RVVBytesPerBlock
So the result is in `[MinVLEN/8, MaxVLEN/8]`.
And, when the maximum VScale is unbounded we fall back to the
architectural maximum VLEN of 65536 (VLENB of 8192).
Fixes #217784.
Assisted-by: TRAE CLI (Opus 4.8)
>From fa06b2d2e382e0c26de88861eb820ea2aa786f12 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <[email protected]>
Date: Mon, 31 Aug 2026 17:07:48 +0800
Subject: [PATCH 1/2] [Clang][RISCV] Add vlenb range-folding baseline tests
(NFC)
Extend the __riscv_vlenb() handcrafted test with comparisons that a range
annotation on the underlying read_register("vlenb") call would let InstCombine
fold, and add a +zvl512b RUN line:
* vlenb >= 16 (always true for VLEN >= 128),
* vlenb > 8192 (never true, VLEN <= 65536),
* vlenb >= 64 (true only when zvl512b guarantees VLEN >= 512).
Assisted-by: TRAE CLI (Opus 4.8)
---
.../RISCV/rvv-intrinsics-handcrafted/vlenb.c | 98 +++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
index 2b8875def7ced..c0a266dd870b1 100644
--- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
@@ -4,6 +4,8 @@
// RUN: | opt -S -O2 | FileCheck --check-prefix=RV32 %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -disable-O0-optnone
-emit-llvm -Qn %s -o - \
// RUN: | opt -S -O2 | FileCheck --check-prefix=RV64 %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b
-disable-O0-optnone -emit-llvm -Qn %s -o - \
+// RUN: | opt -S -O2 | FileCheck --check-prefix=RV64V512 %s
#include <riscv_vector.h>
@@ -17,9 +19,96 @@
// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4:![0-9]+]])
// RV64-NEXT: ret i64 [[TMP0]]
//
+// RV64V512-LABEL: @test_vlenb(
+// RV64V512-NEXT: entry:
+// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4:![0-9]+]])
+// RV64V512-NEXT: ret i64 [[TMP0]]
+//
unsigned long test_vlenb(void) {
return __riscv_vlenb();
}
+
+// VLENB is at least VLEN/8, and the V extension guarantees VLEN >= 128, so
+// vlenb >= 16 always holds. Without a range annotation this does not fold.
+// RV32-LABEL: @test_vlenb_ge_min(
+// RV32-NEXT: entry:
+// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
+// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 15
+// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV32-NEXT: ret i32 [[CONV]]
+//
+// RV64-LABEL: @test_vlenb_ge_min(
+// RV64-NEXT: entry:
+// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
+// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 15
+// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64-NEXT: ret i32 [[CONV]]
+//
+// RV64V512-LABEL: @test_vlenb_ge_min(
+// RV64V512-NEXT: entry:
+// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
+// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 15
+// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64V512-NEXT: ret i32 [[CONV]]
+//
+int test_vlenb_ge_min(void) {
+ return __riscv_vlenb() >= 16;
+}
+
+// VLENB is at most VLEN/8 = 65536/8 = 8192, so vlenb > 8192 is never true.
+// Without a range annotation this does not fold.
+// RV32-LABEL: @test_vlenb_gt_max(
+// RV32-NEXT: entry:
+// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
+// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 8192
+// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV32-NEXT: ret i32 [[CONV]]
+//
+// RV64-LABEL: @test_vlenb_gt_max(
+// RV64-NEXT: entry:
+// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
+// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 8192
+// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64-NEXT: ret i32 [[CONV]]
+//
+// RV64V512-LABEL: @test_vlenb_gt_max(
+// RV64V512-NEXT: entry:
+// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
+// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 8192
+// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64V512-NEXT: ret i32 [[CONV]]
+//
+int test_vlenb_gt_max(void) {
+ return __riscv_vlenb() > 8192;
+}
+
+// With zvl512b the minimum VLEN is 512, so vlenb >= 64 always holds; plain +v
+// only guarantees vlenb >= 16, so it must not fold there. Without a range
+// annotation neither case folds.
+// RV32-LABEL: @test_vlenb_ge_zvl512(
+// RV32-NEXT: entry:
+// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
+// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 63
+// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV32-NEXT: ret i32 [[CONV]]
+//
+// RV64-LABEL: @test_vlenb_ge_zvl512(
+// RV64-NEXT: entry:
+// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
+// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 63
+// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64-NEXT: ret i32 [[CONV]]
+//
+// RV64V512-LABEL: @test_vlenb_ge_zvl512(
+// RV64V512-NEXT: entry:
+// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
+// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 63
+// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+// RV64V512-NEXT: ret i32 [[CONV]]
+//
+int test_vlenb_ge_zvl512(void) {
+ return __riscv_vlenb() >= 64;
+}
//.
// RV32: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+32bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
// RV32: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
@@ -27,6 +116,9 @@ unsigned long test_vlenb(void) {
// RV64: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
// RV64: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
//.
+// RV64V512: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(8,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl256b,+zvl32b,+zvl512b,+zvl64b"
}
+// RV64V512: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
+//.
// RV32: [[META0:![0-9]+]] = !{i32 1, !"target-abi", !"ilp32d"}
// RV32: [[META1:![0-9]+]] = !{i32 6, !"riscv-isa", [[META2:![0-9]+]]}
// RV32: [[META2]] =
!{!"rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"}
@@ -39,3 +131,9 @@ unsigned long test_vlenb(void) {
// RV64: [[META3:![0-9]+]] = !{i32 8, !"SmallDataLimit", i32 0}
// RV64: [[META4]] = !{!"vlenb"}
//.
+// RV64V512: [[META0:![0-9]+]] = !{i32 1, !"target-abi", !"lp64d"}
+// RV64V512: [[META1:![0-9]+]] = !{i32 6, !"riscv-isa", [[META2:![0-9]+]]}
+// RV64V512: [[META2]] =
!{!"rv64i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0"}
+// RV64V512: [[META3:![0-9]+]] = !{i32 8, !"SmallDataLimit", i32 0}
+// RV64V512: [[META4]] = !{!"vlenb"}
+//.
>From 0213110ef9f5ef65038175321f745670ba741401 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <[email protected]>
Date: Mon, 31 Aug 2026 17:16:39 +0800
Subject: [PATCH 2/2] [Clang][RISCV] Attach a range attribute to the vlenb
builtin result
`__riscv_vlenb()` reads the `vlenb` CSR, which holds `VLEN/8`.
In this PR, we attach a range return attribute to the emitted
`read_register("vlenb")` call, derived from the target's VLEN
bounds via `TargetInfo::getVScaleRange()`:
VLENB = VScale * RVVBytesPerBlock
So the result is in `[MinVLEN/8, MaxVLEN/8]`.
And, when the maximum VScale is unbounded we fall back to the
architectural maximum VLEN of 65536 (VLENB of 8192).
Fixes #217784.
Assisted-by: TRAE CLI (Opus 4.8)
---
clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 21 +++++-
.../RISCV/rvv-intrinsics-handcrafted/vlenb.c | 64 +++++++------------
2 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index 66e04f2ea06b3..32dd6738df84d 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -12,6 +12,7 @@
#include "CodeGenFunction.h"
#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
@@ -294,7 +295,25 @@ emitRVVVlenbBuiltin(CodeGenFunction *CGF, const CallExpr
*E,
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, {CGF->SizeTy});
- return Builder.CreateCall(F, Metadata);
+ llvm::CallInst *Result = Builder.CreateCall(F, Metadata);
+
+ // vlenb reads the vlenb CSR, which holds VLEN/8. Attach a range return
+ // attribute derived from the target's VLEN bounds so generic value analyses
+ // (e.g. InstCombine via CallBase::getRange()) can fold vlenb comparisons.
+ // VScale is measured in units of RVVBitsPerBlock, so VLENB = VScale *
+ // RVVBytesPerBlock. A zero upper bound means unbounded, in which case we
fall
+ // back to the architectural maximum VLEN of 65536 (i.e. VLENB of 8192).
+ if (auto VScale = CGM.getTarget().getVScaleRange(
+ CGF->getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming)) {
+ unsigned BitWidth = CGF->SizeTy->getBitWidth();
+ uint64_t Lo = (uint64_t)VScale->first * llvm::RISCV::RVVBytesPerBlock;
+ uint64_t Hi = VScale->second
+ ? (uint64_t)VScale->second *
llvm::RISCV::RVVBytesPerBlock
+ : 65536 / 8;
+ Result->addRangeRetAttr(llvm::ConstantRange(llvm::APInt(BitWidth, Lo),
+ llvm::APInt(BitWidth, Hi +
1)));
+ }
+ return Result;
}
static LLVM_ATTRIBUTE_NOINLINE Value *
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
index c0a266dd870b1..f3ebc6da3bd9b 100644
--- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
@@ -11,17 +11,17 @@
// RV32-LABEL: @test_vlenb(
// RV32-NEXT: entry:
-// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4:![0-9]+]])
+// RV32-NEXT: [[TMP0:%.*]] = tail call range(i32 16, 8193) i32
@llvm.read_register.i32(metadata [[META4:![0-9]+]])
// RV32-NEXT: ret i32 [[TMP0]]
//
// RV64-LABEL: @test_vlenb(
// RV64-NEXT: entry:
-// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4:![0-9]+]])
+// RV64-NEXT: [[TMP0:%.*]] = tail call range(i64 16, 8193) i64
@llvm.read_register.i64(metadata [[META4:![0-9]+]])
// RV64-NEXT: ret i64 [[TMP0]]
//
// RV64V512-LABEL: @test_vlenb(
// RV64V512-NEXT: entry:
-// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4:![0-9]+]])
+// RV64V512-NEXT: [[TMP0:%.*]] = tail call range(i64 64, 8193) i64
@llvm.read_register.i64(metadata [[META4:![0-9]+]])
// RV64V512-NEXT: ret i64 [[TMP0]]
//
unsigned long test_vlenb(void) {
@@ -29,82 +29,61 @@ unsigned long test_vlenb(void) {
}
// VLENB is at least VLEN/8, and the V extension guarantees VLEN >= 128, so
-// vlenb >= 16 always holds. Without a range annotation this does not fold.
+// vlenb >= 16 always holds and the comparison folds to true.
// RV32-LABEL: @test_vlenb_ge_min(
// RV32-NEXT: entry:
-// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
-// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 15
-// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV32-NEXT: ret i32 [[CONV]]
+// RV32-NEXT: ret i32 1
//
// RV64-LABEL: @test_vlenb_ge_min(
// RV64-NEXT: entry:
-// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
-// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 15
-// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV64-NEXT: ret i32 [[CONV]]
+// RV64-NEXT: ret i32 1
//
// RV64V512-LABEL: @test_vlenb_ge_min(
// RV64V512-NEXT: entry:
-// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
-// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 15
-// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV64V512-NEXT: ret i32 [[CONV]]
+// RV64V512-NEXT: ret i32 1
//
int test_vlenb_ge_min(void) {
return __riscv_vlenb() >= 16;
}
-// VLENB is at most VLEN/8 = 65536/8 = 8192, so vlenb > 8192 is never true.
-// Without a range annotation this does not fold.
+// VLENB is at most VLEN/8 = 65536/8 = 8192, so vlenb > 8192 is never true and
+// the comparison folds to false.
// RV32-LABEL: @test_vlenb_gt_max(
// RV32-NEXT: entry:
-// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
-// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 8192
-// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV32-NEXT: ret i32 [[CONV]]
+// RV32-NEXT: ret i32 0
//
// RV64-LABEL: @test_vlenb_gt_max(
// RV64-NEXT: entry:
-// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
-// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 8192
-// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV64-NEXT: ret i32 [[CONV]]
+// RV64-NEXT: ret i32 0
//
// RV64V512-LABEL: @test_vlenb_gt_max(
// RV64V512-NEXT: entry:
-// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
-// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 8192
-// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV64V512-NEXT: ret i32 [[CONV]]
+// RV64V512-NEXT: ret i32 0
//
int test_vlenb_gt_max(void) {
return __riscv_vlenb() > 8192;
}
-// With zvl512b the minimum VLEN is 512, so vlenb >= 64 always holds; plain +v
-// only guarantees vlenb >= 16, so it must not fold there. Without a range
-// annotation neither case folds.
+// With zvl512b the minimum VLEN is 512, so vlenb >= 64 always holds and folds
+// to true there; plain +v only guarantees vlenb >= 16, so the comparison must
+// stay for the RV32/RV64 (VLEN128) runs.
// RV32-LABEL: @test_vlenb_ge_zvl512(
// RV32-NEXT: entry:
-// RV32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.read_register.i32(metadata
[[META4]])
-// RV32-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0]], 63
+// RV32-NEXT: [[TMP0:%.*]] = tail call range(i32 16, 8193) i32
@llvm.read_register.i32(metadata [[META4]])
+// RV32-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[TMP0]], 63
// RV32-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
// RV32-NEXT: ret i32 [[CONV]]
//
// RV64-LABEL: @test_vlenb_ge_zvl512(
// RV64-NEXT: entry:
-// RV64-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.read_register.i64(metadata
[[META4]])
-// RV64-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 63
+// RV64-NEXT: [[TMP0:%.*]] = tail call range(i64 16, 8193) i64
@llvm.read_register.i64(metadata [[META4]])
+// RV64-NEXT: [[CMP:%.*]] = icmp samesign ugt i64 [[TMP0]], 63
// RV64-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
// RV64-NEXT: ret i32 [[CONV]]
//
// RV64V512-LABEL: @test_vlenb_ge_zvl512(
// RV64V512-NEXT: entry:
-// RV64V512-NEXT: [[TMP0:%.*]] = tail call i64
@llvm.read_register.i64(metadata [[META4]])
-// RV64V512-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], 63
-// RV64V512-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-// RV64V512-NEXT: ret i32 [[CONV]]
+// RV64V512-NEXT: ret i32 1
//
int test_vlenb_ge_zvl512(void) {
return __riscv_vlenb() >= 64;
@@ -112,12 +91,15 @@ int test_vlenb_ge_zvl512(void) {
//.
// RV32: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+32bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
// RV32: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
+// RV32: attributes #[[ATTR2:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(none) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+32bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
//.
// RV64: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
// RV64: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
+// RV64: attributes #[[ATTR2:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(none) vscale_range(2,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b"
}
//.
// RV64V512: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(read) vscale_range(8,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl256b,+zvl32b,+zvl512b,+zvl64b"
}
// RV64V512: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree
nosync nounwind willreturn memory(read) }
+// RV64V512: attributes #[[ATTR2:[0-9]+]] = { mustprogress nofree noinline
norecurse nosync nounwind willreturn memory(none) vscale_range(8,1024)
"no-trapping-math"="true" "stack-protector-buffer-size"="8"
"target-features"="+64bit,+d,+f,+i,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl256b,+zvl32b,+zvl512b,+zvl64b"
}
//.
// RV32: [[META0:![0-9]+]] = !{i32 1, !"target-abi", !"ilp32d"}
// RV32: [[META1:![0-9]+]] = !{i32 6, !"riscv-isa", [[META2:![0-9]+]]}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits