[clang] [llvm] [inlineasm] Improve support for multiple inline asm constraints (e.g. "rm") (PR #197798)

Nick Desaulniers via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 8 11:53:23 PDT 2026


================
@@ -16303,6 +16303,56 @@ Example:
         call void @llvm.call.preallocated.teardown(token %cs)
         ret void
 
+.. _int_asm_constraint_br:
+
+'``llvm.asm.constraint.br``'
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+      declare void @llvm.asm.constraint.br()
+
+Overview:
+"""""""""
+
+The '``llvm.asm.constraint.br``' intrinsic is used when an inline asm
+constraint allows for either register or memory, e.g., '``"rm"``'.
+
+Semantics:
+""""""""""
+
+The '``llvm.asm.constraint.br``' allows the back-end to choose the best
+constraint rather than restricting the preferred constraint to one that may
+produce substandard code or cannot be handled by the register allocators.
+
+It can be called only by the '``callbr``' instruction. The default destination
+of the ``callbr`` contains a call to the preferred inline asm, while the single
+indirect destination contains a call to the pessimal inline asm.
+
+Example:
+""""""""
+
+.. code-block:: llvm
+
+      %out = alloca i64, align 8
+      callbr void @llvm.asm.constraint.br()
+              to label %asm.pref.reg [label %asm.pref.mem]
----------------
nickdesaulniers wrote:

Question for @nikic and @arsenm (or other observers):

So this pattern of essentially leaving a TODO branch for control flow still doesn't sit quite right with me.

2 things come to mind.

1. I don't like having an intrinsic here because now we need entries in the langref and verifier for it.  But I don't consider this a blocker, given the below code snippet.
2. this isn't really what callbr was designed for.  We only ever have 2 possible branches, so squirling away the branch list in the indirect labels list is *clever* but perhaps too clever IMO.

I had asked @bwendling "why not just use a [`br` instruction](https://llvm.org/docs/LangRef.html#br-instruction) with metadata?"  @bwendling mentioned concerns about passes dropping metadata being a risk.  I figured we'd need some value in that case to branch on, and @bwendling mentioned that SimplifyCFG would likely remove the `br` if we branched on something like `undef`.  Is there another pattern you can think of (possible prior art) that might work better here?

Maybe we'd keep the intrinsic, but replace callbr with a `br`?

Example:
```llvm
%pick_one = call i1 @llvm.as.constraint.br()
br i1 %pick_one, label %asm.pref.reg, label %asm.pref.mem
```

https://github.com/llvm/llvm-project/pull/197798


More information about the cfe-commits mailing list