Skip to content

[Xtensa] Support 'f' Inline Assembly Constraint#202345

Open
gerekon wants to merge 1 commit into
llvm:mainfrom
gerekon:feat/llvm_xtensa_f_constr
Open

[Xtensa] Support 'f' Inline Assembly Constraint#202345
gerekon wants to merge 1 commit into
llvm:mainfrom
gerekon:feat/llvm_xtensa_f_constr

Conversation

@gerekon
Copy link
Copy Markdown
Contributor

@gerekon gerekon commented Jun 8, 2026

This adds the 'f' inline assembly constraint, as supported by GCC. An 'f'-constrained operand is passed in a floating point register.

This adds the 'f' inline assembly constraint, as supported by GCC. An
'f'-constrained operand is passed in a floating point register.
@llvmorg-github-actions
Copy link
Copy Markdown

@llvm/pr-subscribers-backend-xtensa

Author: Alexey Gerenkov (gerekon)

Changes

This adds the 'f' inline assembly constraint, as supported by GCC. An 'f'-constrained operand is passed in a floating point register.


Full diff: https://github.com/llvm/llvm-project/pull/202345.diff

3 Files Affected:

  • (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+8)
  • (added) llvm/test/CodeGen/Xtensa/inline-asm-constraints.ll (+23)
  • (modified) llvm/test/CodeGen/Xtensa/inline-asm-invalid.ll (+2-9)
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 923afb2ec1b3d..fbe497cc66056 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -287,6 +287,7 @@ XtensaTargetLowering::getConstraintType(StringRef Constraint) const {
   if (Constraint.size() == 1) {
     switch (Constraint[0]) {
     case 'r':
+    case 'f':
       return C_RegisterClass;
     default:
       break;
@@ -316,6 +317,10 @@ XtensaTargetLowering::getSingleConstraintMatchWeight(
     if (Ty->isIntegerTy())
       Weight = CW_Register;
     break;
+  case 'f':
+    if (Ty->isFloatingPointTy())
+      Weight = CW_Register;
+    break;
   }
   return Weight;
 }
@@ -330,6 +335,9 @@ XtensaTargetLowering::getRegForInlineAsmConstraint(
       break;
     case 'r': // General-purpose register
       return std::make_pair(0U, &Xtensa::ARRegClass);
+    case 'f': // Floating-point register
+      if (Subtarget.hasSingleFloat())
+        return std::make_pair(0U, &Xtensa::FPRRegClass);
     }
   }
   return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
diff --git a/llvm/test/CodeGen/Xtensa/inline-asm-constraints.ll b/llvm/test/CodeGen/Xtensa/inline-asm-constraints.ll
new file mode 100644
index 0000000000000..7dbb0f07debda
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/inline-asm-constraints.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple=xtensa  -mcpu=esp32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=Xtensa %s
+
+
+@gf = external global float
+
+define float @constraint_f_float(float %a) nounwind {
+; Xtensa-LABEL: constraint_f_float:
+; Xtensa:       # %bb.0:
+; Xtensa-NEXT:    entry a1, 32
+; Xtensa-NEXT:    wfr f8, a2
+; Xtensa-NEXT:    l32r a8, .LCPI0_0
+; Xtensa-NEXT:    lsi f9, a8, 0
+; Xtensa-NEXT:    #APP
+; Xtensa-NEXT:    add.s f8, f8, f9
+; Xtensa-NEXT:    #NO_APP
+; Xtensa-NEXT:    rfr a2, f8
+; Xtensa-NEXT:    retw
+  %1 = load float, float* @gf
+  %2 = tail call float asm "add.s $0, $1, $2", "=f,f,f"(float %a, float %1)
+  ret float %2
+}
+
diff --git a/llvm/test/CodeGen/Xtensa/inline-asm-invalid.ll b/llvm/test/CodeGen/Xtensa/inline-asm-invalid.ll
index cb9cd83fbc156..2da5fcc3fb97b 100644
--- a/llvm/test/CodeGen/Xtensa/inline-asm-invalid.ll
+++ b/llvm/test/CodeGen/Xtensa/inline-asm-invalid.ll
@@ -1,14 +1,7 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: not llc --mtriple=xtensa < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=xtensa -mcpu=generic < %s 2>&1 | FileCheck %s
 
+; CHECK: error: could not allocate input reg for constraint 'f'
 define void @constraint_f() nounwind {
-; CHECK: error: unknown asm constraint 'f'
   tail call void asm "add.s f0, f1, $0", "f"(float 0.0)
   ret void
 }
-
-define i32 @register_a100(i32 %a) nounwind {
-; CHECK: error: could not allocate input reg for constraint '{$a100}'
-  %1 = tail call i32 asm "addi $0, $1, 1", "=r,{$a100}"(i32 %a)
-  ret i32 %1
-}

@gerekon
Copy link
Copy Markdown
Contributor Author

gerekon commented Jun 8, 2026

@andreisfr PTAL

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 8, 2026

🐧 Linux x64 Test Results

  • 175220 tests passed
  • 3445 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

lldb-unit

lldb-unit.DAP/_/DAPTests/DAPSessionManagerTest/WaitForAllSessionsToDisconnect
Script:
--
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb/unittests/DAP/./DAPTests --gtest_filter=DAPSessionManagerTest.WaitForAllSessionsToDisconnect
--
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/unittests/DAP/DAPSessionManagerTest.cpp:96
Expected: (duration) >= (std::chrono::milliseconds(100)), actual: 8-byte object <EC-7D DA-05 00-00 00-00> vs 8-byte object <64-00 00-00 00-00 00-00>


If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant