[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 cfe-commits@lists.llvm.org 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 cfe-commits@lists.llvm.org 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