-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RISC-V] Allow intrinsics to be used with any pointer type. #139634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
RISC-V does not use address spaces and leaves them available for user code to make use of. Intrinsics, however, required pointer types to use the default address space, complicating handling during lowering to handle non-default address spaces. When the intrinsics are overloaded, this is handled without extra effort. This commit does not yet update Clang builtin functions to also permit pointers to non-default address spaces.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-transforms Author: Harald van Dijk (hvdijk) ChangesRISC-V does not use address spaces and leaves them available for user code to make use of. Intrinsics, however, required pointer types to use the default address space, complicating handling during lowering to handle non-default address spaces. When the intrinsics are overloaded, this is handled without extra effort. This commit does not yet update Clang builtin functions to also permit pointers to non-default address spaces. Patch is 56.31 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139634.diff 1138 Files Affected:
diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td
index c1446a5070326..bff8699463c43 100644
--- a/clang/include/clang/Basic/riscv_vector.td
+++ b/clang/include/clang/Basic/riscv_vector.td
@@ -26,7 +26,7 @@ class IsFloat<string type> {
let SupportOverloading = false,
MaskedPolicyScheme = NonePolicy in {
- class RVVVLEMaskBuiltin : RVVOutBuiltin<"m", "mPCUe", "c"> {
+ class RVVVLEMaskBuiltin : RVVOutOp0Builtin<"m", "mPCUe", "c"> {
let Name = "vlm_v";
let IRName = "vlm";
let HasMasked = false;
@@ -40,9 +40,9 @@ let SupportOverloading = false,
IRName = "vle",
MaskedIRName ="vle_mask" in {
foreach type = types in {
- def : RVVOutBuiltin<"v", "vPCe", type>;
+ def : RVVOutOp0Builtin<"v", "vPCe", type>;
if !not(IsFloat<type>.val) then {
- def : RVVOutBuiltin<"Uv", "UvPCUe", type>;
+ def : RVVOutOp0Builtin<"Uv", "UvPCUe", type>;
}
}
}
@@ -63,11 +63,11 @@ multiclass RVVVLEFFBuiltin<list<string> types> {
if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
- IntrinsicTypes = {ResultType, Ops[4]->getType()};
+ IntrinsicTypes = {ResultType, Ops[4]->getType(), Ops[2]->getType()};
} else {
if (PolicyAttrs & RVV_VTA)
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
- IntrinsicTypes = {ResultType, Ops[3]->getType()};
+ IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[1]->getType()};
}
Value *NewVL = Ops[2];
Ops.erase(Ops.begin() + 2);
@@ -102,9 +102,9 @@ multiclass RVVVLSEBuiltin<list<string> types> {
SupportOverloading = false,
UnMaskedPolicyScheme = HasPassthruOperand in {
foreach type = types in {
- def : RVVOutBuiltin<"v", "vPCet", type>;
+ def : RVVOutOp0Builtin<"v", "vPCet", type>;
if !not(IsFloat<type>.val) then {
- def : RVVOutBuiltin<"Uv", "UvPCUet", type>;
+ def : RVVOutOp0Builtin<"Uv", "UvPCUet", type>;
}
}
}
@@ -120,9 +120,9 @@ multiclass RVVIndexedLoad<string op> {
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
!if(!eq(type, "y"), ["Zvfbfmin"],
[]<string>)) in {
- def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
+ def: RVVOutOp0Op1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
if !not(IsFloat<type>.val) then {
- def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
+ def: RVVOutOp0Op1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
}
}
}
@@ -132,9 +132,9 @@ multiclass RVVIndexedLoad<string op> {
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
!if(!eq(type, "y"), ["Zvfbfmin", "RV64"],
["RV64"])) in {
- def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
+ def: RVVOutOp0Op1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
if !not(IsFloat<type>.val) then {
- def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>;
+ def: RVVOutOp0Op1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>;
}
}
}
@@ -152,9 +152,9 @@ let HasMaskedOffOperand = false,
std::swap(Ops[0], Ops[1]);
}
if (IsMasked)
- IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
else
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};
}] in {
class RVVVSEMaskBuiltin : RVVBuiltin<"m", "0PUem", "c"> {
let Name = "vsm_v";
@@ -190,9 +190,9 @@ multiclass RVVVSSEBuiltin<list<string> types> {
std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
}
if (IsMasked)
- IntrinsicTypes = {Ops[0]->getType(), Ops[4]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType()};
else
- IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
}] in {
foreach type = types in {
def : RVVBuiltin<"v", "0Petv", type>;
@@ -215,9 +215,9 @@ multiclass RVVIndexedStore<string op> {
std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
}
if (IsMasked)
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[4]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(), Ops[4]->getType()};
else
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[3]->getType()};
+ IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(), Ops[3]->getType()};
}] in {
foreach type = TypeList in {
foreach eew_list = EEWList[0-2] in {
@@ -762,10 +762,6 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
[]<string>)),
ManualCodegen = [{
{
- if (IsMasked)
- IntrinsicTypes = {ResultType, Ops[0]->getType(), Ops.back()->getType()};
- else
- IntrinsicTypes = {ResultType, Ops.back()->getType()};
SmallVector<llvm::Value*, 6> Operands;
bool NoPassthru =
@@ -773,6 +769,11 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
(!IsMasked && (PolicyAttrs & RVV_VTA));
unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+ if (IsMasked)
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[0]->getType(), Ops.back()->getType()};
+ else
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType()};
+
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
@@ -845,9 +846,9 @@ multiclass RVVUnitStridedSegStoreTuple<string op> {
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
- IntrinsicTypes = {Operands[0]->getType(), Ops[0]->getType(), Operands.back()->getType()};
+ IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[0]->getType(), Operands.back()->getType()};
else
- IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()};
+ IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
}
@@ -882,10 +883,6 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
[]<string>)),
ManualCodegen = [{
{
- if (IsMasked)
- IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[0]->getType()};
- else
- IntrinsicTypes = {ResultType, Ops.back()->getType()};
SmallVector<llvm::Value*, 6> Operands;
bool NoPassthru =
@@ -893,6 +890,11 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
(!IsMasked && (PolicyAttrs & RVV_VTA));
unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+ if (IsMasked)
+ IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[Offset]->getType(), Ops[0]->getType()};
+ else
+ IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[Offset]->getType()};
+
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
@@ -957,10 +959,6 @@ multiclass RVVStridedSegLoadTuple<string op> {
[]<string>)),
ManualCodegen = [{
{
- if (IsMasked)
- IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[0]->getType()};
- else
- IntrinsicTypes = {ResultType, Ops.back()->getType()};
SmallVector<llvm::Value*, 7> Operands;
bool NoPassthru =
@@ -968,6 +966,11 @@ multiclass RVVStridedSegLoadTuple<string op> {
(!IsMasked && (PolicyAttrs & RVV_VTA));
unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+ if (IsMasked)
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType(), Ops[0]->getType()};
+ else
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType()};
+
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
@@ -1043,9 +1046,9 @@ multiclass RVVStridedSegStoreTuple<string op> {
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
- IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType(), Ops[0]->getType()};
+ IntrinsicTypes = {Operands[0]->getType(), Operands[1]->getType(), Operands.back()->getType(), Ops[0]->getType()};
else
- IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()};
+ IntrinsicTypes = {Operands[0]->getType(), Operands[1]->getType(), Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
}
@@ -1099,11 +1102,13 @@ multiclass RVVIndexedSegLoadTuple<string op> {
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
- IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(),
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
+ Ops[Offset + 1]->getType(),
Ops[0]->getType(),
Ops.back()->getType()};
else
- IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(),
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
+ Ops[Offset + 1]->getType(),
Ops.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
@@ -1160,11 +1165,11 @@ multiclass RVVIndexedSegStoreTuple<string op> {
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
- IntrinsicTypes = {Operands[0]->getType(), Ops[Offset + 1]->getType(),
+ IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
Ops[0]->getType(),
Operands.back()->getType()};
else
- IntrinsicTypes = {Operands[0]->getType(), Ops[Offset + 1]->getType(),
+ IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
diff --git a/clang/include/clang/Basic/riscv_vector_common.td b/clang/include/clang/Basic/riscv_vector_common.td
index ee06d740bb168..5a81376208f70 100644
--- a/clang/include/clang/Basic/riscv_vector_common.td
+++ b/clang/include/clang/Basic/riscv_vector_common.td
@@ -266,6 +266,11 @@ class RVVOp0Builtin<string suffix, string prototype, string type_range>
let IntrinsicTypes = [0];
}
+class RVVOutOp0Builtin<string suffix, string prototype, string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [-1, 0];
+}
+
class RVVOutOp1Builtin<string suffix, string prototype, string type_range>
: RVVBuiltin<suffix, prototype, type_range> {
let IntrinsicTypes = [-1, 1];
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16.c
index e0ccab4e46d3b..0588604bb1d19 100644
--- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16.c
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16.c
@@ -11,7 +11,7 @@
// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vle16_v_bf16mf4(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vle.nxv1bf16.i64(<vscale x 1 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vle.nxv1bf16.p0.i64(<vscale x 1 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vle16_v_bf16mf4(const __bf16 *rs1, size_t vl) {
@@ -21,7 +21,7 @@ vbfloat16mf4_t test_vle16_v_bf16mf4(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vle16_v_bf16mf2(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vle.nxv2bf16.i64(<vscale x 2 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vle.nxv2bf16.p0.i64(<vscale x 2 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vle16_v_bf16mf2(const __bf16 *rs1, size_t vl) {
@@ -31,7 +31,7 @@ vbfloat16mf2_t test_vle16_v_bf16mf2(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vle16_v_bf16m1(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vle.nxv4bf16.i64(<vscale x 4 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vle.nxv4bf16.p0.i64(<vscale x 4 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vle16_v_bf16m1(const __bf16 *rs1, size_t vl) {
@@ -41,7 +41,7 @@ vbfloat16m1_t test_vle16_v_bf16m1(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vle16_v_bf16m2(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vle.nxv8bf16.i64(<vscale x 8 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vle.nxv8bf16.p0.i64(<vscale x 8 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vle16_v_bf16m2(const __bf16 *rs1, size_t vl) {
@@ -51,7 +51,7 @@ vbfloat16m2_t test_vle16_v_bf16m2(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vle16_v_bf16m4(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vle.nxv16bf16.i64(<vscale x 16 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vle.nxv16bf16.p0.i64(<vscale x 16 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vle16_v_bf16m4(const __bf16 *rs1, size_t vl) {
@@ -61,7 +61,7 @@ vbfloat16m4_t test_vle16_v_bf16m4(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vle16_v_bf16m8(
// CHECK-RV64-SAME: ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vle.nxv32bf16.i64(<vscale x 32 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vle.nxv32bf16.p0.i64(<vscale x 32 x bfloat> poison, ptr [[RS1]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vle16_v_bf16m8(const __bf16 *rs1, size_t vl) {
@@ -71,7 +71,7 @@ vbfloat16m8_t test_vle16_v_bf16m8(const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vle16_v_bf16mf4_m(
// CHECK-RV64-SAME: <vscale x 1 x i1> [[VM:%.*]], ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vle.mask.nxv1bf16.i64(<vscale x 1 x bfloat> poison, ptr [[RS1]], <vscale x 1 x i1> [[VM]], i64 [[VL]], i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vle.mask.nxv1bf16.p0.i64(<vscale x 1 x bfloat> poison, ptr [[RS1]], <vscale x 1 x i1> [[VM]], i64 [[VL]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vle16_v_bf16mf4_m(vbool64_t vm, const __bf16 *rs1,
@@ -82,7 +82,7 @@ vbfloat16mf4_t test_vle16_v_bf16mf4_m(vbool64_t vm, const __bf16 *rs1,
// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vle16_v_bf16mf2_m(
// CHECK-RV64-SAME: <vscale x 2 x i1> [[VM:%.*]], ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vle.mask.nxv2bf16.i64(<vscale x 2 x bfloat> poison, ptr [[RS1]], <vscale x 2 x i1> [[VM]], i64 [[VL]], i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vle.mask.nxv2bf16.p0.i64(<vscale x 2 x bfloat> poison, ptr [[RS1]], <vscale x 2 x i1> [[VM]], i64 [[VL]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vle16_v_bf16mf2_m(vbool32_t vm, const __bf16 *rs1,
@@ -93,7 +93,7 @@ vbfloat16mf2_t test_vle16_v_bf16mf2_m(vbool32_t vm, const __bf16 *rs1,
// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vle16_v_bf16m1_m(
// CHECK-RV64-SAME: <vscale x 4 x i1> [[VM:%.*]], ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vle.mask.nxv4bf16.i64(<vscale x 4 x bfloat> poison, ptr [[RS1]], <vscale x 4 x i1> [[VM]], i64 [[VL]], i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vle.mask.nxv4bf16.p0.i64(<vscale x 4 x bfloat> poison, ptr [[RS1]], <vscale x 4 x i1> [[VM]], i64 [[VL]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vle16_v_bf16m1_m(vbool16_t vm, const __bf16 *rs1,
@@ -104,7 +104,7 @@ vbfloat16m1_t test_vle16_v_bf16m1_m(vbool16_t vm, const __bf16 *rs1,
// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vle16_v_bf16m2_m(
// CHECK-RV64-SAME: <vscale x 8 x i1> [[VM:%.*]], ptr noundef [[RS1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
-// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vle.mask.nxv8bf16.i64(<vscale x 8 x bfloat> poison, ptr [[RS1]], <vscale x 8 x i1> [[VM]], i64 [[VL]], i64 3)
+// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vle.mask.nxv8bf16.p0.i64(<vscale x 8 x bfloat> poison, ptr [[RS1]], <vscale x 8 x i1> [[VM]], i64 [[VL]], i64 3)
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vle16_v_bf16m2_m(vbool8_t vm, const __bf16 *rs1, size_t vl) {
@@ -114,7 +114,7 @@ vbfloat16m2_t test_vle16_v_bf16m2_m(vbool8_t vm, const __bf16 *rs1, size_t vl) {
// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vle16_v_bf16m4_m(
// CHECK-RV64-SAME: <vscale x 16...
[truncated]
|
At the moment this leaves a bunch of LLVM tests using the old overload name for builtins, which is silently accepted because |
I don't know how many users are requiring this change, but I do know some people are developing RVV-based heterogeneous hardware/software. I am happy to see this and we should make more people be aware of this change, so I suggest to post it on Discourse as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is too huge and it almost makes my Chrome broken. :-(
This fixes a crash introduced in llvm#137045 (comment) where we don't have overloaded pointer types for segmented load/store intrinsics. This should be temporary until llvm#139634 lands and overloads the pointer type for these
I don't think there is a way to meaningfully split this up, sorry. The changes to
My primary motivation for this specific PR is making sure RISCVISelLowering can handle anything. I would not expect this to benefit people using the intrinsics directly just yet, as Clang's builtin functions have not yet been updated. I think it makes more sense to announce it more broadly after we've been able to update those as well? |
Linking some context here, IIUC the use case for this is for OpenCL where device code would use a non-default address space: #137045 (comment) |
…139698) This fixes a crash introduced in #137045 (comment) where we don't have overloaded pointer types for segmented load/store intrinsics. This should be temporary until #139634 lands and overloads the pointer type for these
I think Halide will emit RISC-V LLVM IR intrinsics, so it would be good to double check that the code it emits still works fine with these new intrinsics. |
It may not, but this is not a change I'm planning on asking to be backported to release branches, and this is the sort of change that we wouldn't normally expect to remain stable across releases. Certainly Halide have no problem using |
RISC-V does not use address spaces and leaves them available for user code to make use of. Intrinsics, however, required pointer types to use the default address space, complicating handling during lowering to handle non-default address spaces. When the intrinsics are overloaded, this is handled without extra effort.
This commit does not yet update Clang builtin functions to also permit pointers to non-default address spaces.