[clang] [llvm] [Clang][LoongArch] Add inline asm support for the `q` constraint (PR #141037)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 22 04:04:55 PDT 2025
https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/141037
>From 1148711cdfdd5a58960564790509559fa86e2649 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Thu, 22 May 2025 09:59:53 +0800
Subject: [PATCH] [Clang][LoongArch] Add inline asm support for the `q`
constraint
This patch adds support for the `q` constraint:
a general-purpose register except for $r0 and $r1 (for the csrxchg
instruction)
Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684339.html
---
clang/lib/Basic/Targets/LoongArch.cpp | 5 +++++
.../test/CodeGen/LoongArch/inline-asm-constraints.c | 6 ++++++
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 5 +++++
llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll | 12 ++++++++++++
4 files changed, 28 insertions(+)
diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp
index ca742797d7a3b..f4bcb54bd470d 100644
--- a/clang/lib/Basic/Targets/LoongArch.cpp
+++ b/clang/lib/Basic/Targets/LoongArch.cpp
@@ -139,6 +139,11 @@ bool LoongArchTargetInfo::validateAsmConstraint(
// A signed 16-bit constant.
Info.setRequiresImmediate(-32768, 32767);
return true;
+ case 'q':
+ // A general-purpose register except for $r0 and $r1 (for the csrxchg
+ // instruction)
+ Info.setAllowsRegister();
+ return true;
case 'I':
// A signed 12-bit constant (for arithmetic instructions).
Info.setRequiresImmediate(-2048, 2047);
diff --git a/clang/test/CodeGen/LoongArch/inline-asm-constraints.c b/clang/test/CodeGen/LoongArch/inline-asm-constraints.c
index b19494284bd99..ded21206d63bf 100644
--- a/clang/test/CodeGen/LoongArch/inline-asm-constraints.c
+++ b/clang/test/CodeGen/LoongArch/inline-asm-constraints.c
@@ -35,6 +35,12 @@ void test_m(int *p) {
asm volatile("" :: "m"(*(p+4)));
}
+void test_q(void) {
+// CHECK-LABEL: define{{.*}} void @test_q()
+// CHECK: call void asm sideeffect "", "q"(i32 0)
+ asm volatile ("" :: "q"(0));
+}
+
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
// CHECK: call void asm sideeffect "", "I"(i32 2047)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 9774683e16291..50ec0b2e3ca78 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -7276,6 +7276,8 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
// 'm': A memory operand whose address is formed by a base register and
// offset that is suitable for use in instructions with the same
// addressing mode as st.w and ld.w.
+ // 'q': A general-purpose register except for $r0 and $r1 (for the csrxchg
+ // instruction)
// 'I': A signed 12-bit constant (for arithmetic instructions).
// 'J': Integer zero.
// 'K': An unsigned 12-bit constant (for logic instructions).
@@ -7289,6 +7291,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
default:
break;
case 'f':
+ case 'q':
return C_RegisterClass;
case 'l':
case 'I':
@@ -7328,6 +7331,8 @@ LoongArchTargetLowering::getRegForInlineAsmConstraint(
if (VT.isVector())
break;
return std::make_pair(0U, &LoongArch::GPRRegClass);
+ case 'q':
+ return std::make_pair(0U, &LoongArch::GPRNoR0R1RegClass);
case 'f':
if (Subtarget.hasBasicF() && VT == MVT::f32)
return std::make_pair(0U, &LoongArch::FPR32RegClass);
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll
index 4bcc88be97396..73d240b99b0bc 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll
@@ -17,6 +17,18 @@ define i32 @constraint_r(i32 %a, i32 %b) nounwind {
ret i32 %1
}
+define i32 @constraint_q(i32 %a) nounwind {
+; CHECK-LABEL: constraint_q:
+; CHECK: # %bb.0:
+; CHECK-NEXT: move $a1, $zero
+; CHECK-NEXT: #APP
+; CHECK-NEXT: csrxchg $a0, $a1, 0
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: ret
+ %1 = tail call i32 asm "csrxchg $0, $1, $2", "=r,q,i,0"(i32 0, i32 0, i32 %a)
+ ret i32 %1
+}
+
define i32 @constraint_i(i32 %a) nounwind {
; CHECK-LABEL: constraint_i:
; CHECK: # %bb.0:
More information about the cfe-commits
mailing list