[clang] [llvm] [RISCV] Support cR Inline Asm Constraint (PR #124174)
https://github.com/lenary closed https://github.com/llvm/llvm-project/pull/124174 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Support cR Inline Asm Constraint (PR #124174)
https://github.com/lenary created
https://github.com/llvm/llvm-project/pull/124174
This denotes RVC-compatible GPR Pairs, which are used by the Zclsd extension.
C API PR: riscv-non-isa/riscv-c-api-doc#102
>From d26d237f6586b879aab96b5f604e2e85156e778f Mon Sep 17 00:00:00 2001
From: Sam Elliott
Date: Thu, 23 Jan 2025 10:48:08 -0800
Subject: [PATCH] [RISCV] Support cR Inline Asm Constraint
This denotes RVC-compatible GPR Pairs, which are used by the Zclsd
extension.
C API PR: riscv-non-isa/riscv-c-api-doc#102
---
clang/lib/Basic/Targets/RISCV.cpp | 2 +-
clang/test/CodeGen/RISCV/riscv-inline-asm.c | 8 +++
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +-
.../CodeGen/RISCV/rv32-inline-asm-pairs.ll| 70 +++
.../CodeGen/RISCV/rv64-inline-asm-pairs.ll| 70 +++
.../CodeGen/RISCV/zdinx-asm-constraint.ll | 44
6 files changed, 196 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Basic/Targets/RISCV.cpp
b/clang/lib/Basic/Targets/RISCV.cpp
index db23b0c2283385..8167d7603b0e14 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -102,7 +102,7 @@ bool RISCVTargetInfo::validateAsmConstraint(
return true;
case 'c':
// A RVC register - GPR or FPR
-if (Name[1] == 'r' || Name[1] == 'f') {
+if (Name[1] == 'r' || Name[1] == 'R' || Name[1] == 'f') {
Info.setAllowsRegister();
Name += 1;
return true;
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index 9da306807ed0dc..f2031e0adcbcb2 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -46,6 +46,14 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
return ret;
}
+double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
+// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
+// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
+ double_xlen_t ret;
+ asm volatile("" : "=cR"(ret) : "cR"(p));
+ return ret;
+}
+
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
// CHECK: call void asm sideeffect "", "I"(i32 2047)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b25cb128bce9fb..e08b22e1f86fb0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20903,7 +20903,7 @@ RISCVTargetLowering::getConstraintType(StringRef
Constraint) const {
} else {
if (Constraint == "vr" || Constraint == "vd" || Constraint == "vm")
return C_RegisterClass;
-if (Constraint == "cr" || Constraint == "cf")
+if (Constraint == "cr" || Constraint == "cR" || Constraint == "cf")
return C_RegisterClass;
}
return TargetLowering::getConstraintType(Constraint);
@@ -20992,6 +20992,8 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const
TargetRegisterInfo *TRI,
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
if (!VT.isVector())
return std::make_pair(0U, &RISCV::GPRCRegClass);
+ } else if (Constraint == "cR") {
+ return std::make_pair(0U, &RISCV::GPRPairCRegClass);
} else if (Constraint == "cf") {
if (VT == MVT::f16) {
if (Subtarget.hasStdExtZfhmin())
diff --git a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
index 04a5d268aebff7..f14fe2665835e4 100644
--- a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
@@ -71,3 +71,73 @@ entry:
%9 = load i64, ptr %3, align 8
ret i64 %9
}
+
+define i64 @test_cR_wide_scalar_simple(i64 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_simple:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:mv a0, a2
+; CHECK-NEXT:mv a1, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %0)
+ ret i64 %1
+}
+
+define i32 @test_cR_wide_scalar_with_ops(i32 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_with_ops:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:mv a1, a0
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:or a0, a2, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = zext i32 %0 to i64
+ %2 = shl i64 %1, 32
+ %3 = or i64 %1, %2
+ %4 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %3)
+ %5 = trunc i64 %4 to i32
+ %6 = lshr i64 %4, 32
+ %7 = trunc i64 %6 to i32
+ %8 = or i32 %5, %7
+ ret i32 %8
+}
+
+define i64 @test_cR_wide_scalar_inout(ptr %0, i64 noundef %1) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_inout:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:addi sp, sp, -16
+; CHECK-NEXT:mv a3, a2
+; CHECK-NEXT:sw a0, 12(sp)
+; CHECK-NEXT:mv a2, a1
+; CHECK-NEXT:sw a1, 0(sp)
+; CHECK-NEXT:sw a3, 4(sp)
[clang] [llvm] [RISCV] Support cR Inline Asm Constraint (PR #124174)
https://github.com/topperc approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/124174 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Support cR Inline Asm Constraint (PR #124174)
https://github.com/lenary updated
https://github.com/llvm/llvm-project/pull/124174
>From d26d237f6586b879aab96b5f604e2e85156e778f Mon Sep 17 00:00:00 2001
From: Sam Elliott
Date: Thu, 23 Jan 2025 10:48:08 -0800
Subject: [PATCH 1/2] [RISCV] Support cR Inline Asm Constraint
This denotes RVC-compatible GPR Pairs, which are used by the Zclsd
extension.
C API PR: riscv-non-isa/riscv-c-api-doc#102
---
clang/lib/Basic/Targets/RISCV.cpp | 2 +-
clang/test/CodeGen/RISCV/riscv-inline-asm.c | 8 +++
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +-
.../CodeGen/RISCV/rv32-inline-asm-pairs.ll| 70 +++
.../CodeGen/RISCV/rv64-inline-asm-pairs.ll| 70 +++
.../CodeGen/RISCV/zdinx-asm-constraint.ll | 44
6 files changed, 196 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Basic/Targets/RISCV.cpp
b/clang/lib/Basic/Targets/RISCV.cpp
index db23b0c2283385..8167d7603b0e14 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -102,7 +102,7 @@ bool RISCVTargetInfo::validateAsmConstraint(
return true;
case 'c':
// A RVC register - GPR or FPR
-if (Name[1] == 'r' || Name[1] == 'f') {
+if (Name[1] == 'r' || Name[1] == 'R' || Name[1] == 'f') {
Info.setAllowsRegister();
Name += 1;
return true;
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index 9da306807ed0dc..f2031e0adcbcb2 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -46,6 +46,14 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
return ret;
}
+double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
+// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
+// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
+ double_xlen_t ret;
+ asm volatile("" : "=cR"(ret) : "cR"(p));
+ return ret;
+}
+
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
// CHECK: call void asm sideeffect "", "I"(i32 2047)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b25cb128bce9fb..e08b22e1f86fb0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20903,7 +20903,7 @@ RISCVTargetLowering::getConstraintType(StringRef
Constraint) const {
} else {
if (Constraint == "vr" || Constraint == "vd" || Constraint == "vm")
return C_RegisterClass;
-if (Constraint == "cr" || Constraint == "cf")
+if (Constraint == "cr" || Constraint == "cR" || Constraint == "cf")
return C_RegisterClass;
}
return TargetLowering::getConstraintType(Constraint);
@@ -20992,6 +20992,8 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const
TargetRegisterInfo *TRI,
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
if (!VT.isVector())
return std::make_pair(0U, &RISCV::GPRCRegClass);
+ } else if (Constraint == "cR") {
+ return std::make_pair(0U, &RISCV::GPRPairCRegClass);
} else if (Constraint == "cf") {
if (VT == MVT::f16) {
if (Subtarget.hasStdExtZfhmin())
diff --git a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
index 04a5d268aebff7..f14fe2665835e4 100644
--- a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
@@ -71,3 +71,73 @@ entry:
%9 = load i64, ptr %3, align 8
ret i64 %9
}
+
+define i64 @test_cR_wide_scalar_simple(i64 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_simple:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:mv a0, a2
+; CHECK-NEXT:mv a1, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %0)
+ ret i64 %1
+}
+
+define i32 @test_cR_wide_scalar_with_ops(i32 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_with_ops:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:mv a1, a0
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:or a0, a2, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = zext i32 %0 to i64
+ %2 = shl i64 %1, 32
+ %3 = or i64 %1, %2
+ %4 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %3)
+ %5 = trunc i64 %4 to i32
+ %6 = lshr i64 %4, 32
+ %7 = trunc i64 %6 to i32
+ %8 = or i32 %5, %7
+ ret i32 %8
+}
+
+define i64 @test_cR_wide_scalar_inout(ptr %0, i64 noundef %1) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_inout:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:addi sp, sp, -16
+; CHECK-NEXT:mv a3, a2
+; CHECK-NEXT:sw a0, 12(sp)
+; CHECK-NEXT:mv a2, a1
+; CHECK-NEXT:sw a1, 0(sp)
+; CHECK-NEXT:sw a3, 4(sp)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a0; a2
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:sw a0, 12(sp)
+; CHECK-NEX
[clang] [llvm] [RISCV] Support cR Inline Asm Constraint (PR #124174)
llvmbot wrote:
@llvm/pr-subscribers-backend-risc-v
Author: Sam Elliott (lenary)
Changes
This denotes RVC-compatible GPR Pairs, which are used by the Zclsd extension.
C API PR: riscv-non-isa/riscv-c-api-doc#102
---
Full diff: https://github.com/llvm/llvm-project/pull/124174.diff
6 Files Affected:
- (modified) clang/lib/Basic/Targets/RISCV.cpp (+1-1)
- (modified) clang/test/CodeGen/RISCV/riscv-inline-asm.c (+8)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+3-1)
- (modified) llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll (+70)
- (modified) llvm/test/CodeGen/RISCV/rv64-inline-asm-pairs.ll (+70)
- (modified) llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll (+44)
``diff
diff --git a/clang/lib/Basic/Targets/RISCV.cpp
b/clang/lib/Basic/Targets/RISCV.cpp
index db23b0c2283385..8167d7603b0e14 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -102,7 +102,7 @@ bool RISCVTargetInfo::validateAsmConstraint(
return true;
case 'c':
// A RVC register - GPR or FPR
-if (Name[1] == 'r' || Name[1] == 'f') {
+if (Name[1] == 'r' || Name[1] == 'R' || Name[1] == 'f') {
Info.setAllowsRegister();
Name += 1;
return true;
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index 9da306807ed0dc..f2031e0adcbcb2 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -46,6 +46,14 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
return ret;
}
+double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
+// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
+// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
+ double_xlen_t ret;
+ asm volatile("" : "=cR"(ret) : "cR"(p));
+ return ret;
+}
+
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
// CHECK: call void asm sideeffect "", "I"(i32 2047)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b25cb128bce9fb..e08b22e1f86fb0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20903,7 +20903,7 @@ RISCVTargetLowering::getConstraintType(StringRef
Constraint) const {
} else {
if (Constraint == "vr" || Constraint == "vd" || Constraint == "vm")
return C_RegisterClass;
-if (Constraint == "cr" || Constraint == "cf")
+if (Constraint == "cr" || Constraint == "cR" || Constraint == "cf")
return C_RegisterClass;
}
return TargetLowering::getConstraintType(Constraint);
@@ -20992,6 +20992,8 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const
TargetRegisterInfo *TRI,
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
if (!VT.isVector())
return std::make_pair(0U, &RISCV::GPRCRegClass);
+ } else if (Constraint == "cR") {
+ return std::make_pair(0U, &RISCV::GPRPairCRegClass);
} else if (Constraint == "cf") {
if (VT == MVT::f16) {
if (Subtarget.hasStdExtZfhmin())
diff --git a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
index 04a5d268aebff7..f14fe2665835e4 100644
--- a/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll
@@ -71,3 +71,73 @@ entry:
%9 = load i64, ptr %3, align 8
ret i64 %9
}
+
+define i64 @test_cR_wide_scalar_simple(i64 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_simple:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:mv a0, a2
+; CHECK-NEXT:mv a1, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %0)
+ ret i64 %1
+}
+
+define i32 @test_cR_wide_scalar_with_ops(i32 noundef %0) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_with_ops:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:mv a1, a0
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a2 <- a0
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:or a0, a2, a3
+; CHECK-NEXT:ret
+entry:
+ %1 = zext i32 %0 to i64
+ %2 = shl i64 %1, 32
+ %3 = or i64 %1, %2
+ %4 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %3)
+ %5 = trunc i64 %4 to i32
+ %6 = lshr i64 %4, 32
+ %7 = trunc i64 %6 to i32
+ %8 = or i32 %5, %7
+ ret i32 %8
+}
+
+define i64 @test_cR_wide_scalar_inout(ptr %0, i64 noundef %1) nounwind {
+; CHECK-LABEL: test_cR_wide_scalar_inout:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT:addi sp, sp, -16
+; CHECK-NEXT:mv a3, a2
+; CHECK-NEXT:sw a0, 12(sp)
+; CHECK-NEXT:mv a2, a1
+; CHECK-NEXT:sw a1, 0(sp)
+; CHECK-NEXT:sw a3, 4(sp)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:# a0; a2
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:sw a0, 12(sp)
+; CHECK-NEXT:sw a2, 0(sp)
+; CHECK-NEXT:sw a3, 4(sp)
+; CHECK-NEXT:mv a0, a2
+; CHECK-NEXT:mv a1, a3
+; CHECK-N
