* [PATCH RFC v2] riscv: Use 64-bit variable for output in __get_user_asm
@ 2026-01-14 0:09 Nathan Chancellor
2026-01-15 1:02 ` Paul Walmsley
0 siblings, 1 reply; 3+ messages in thread
From: Nathan Chancellor @ 2026-01-14 0:09 UTC (permalink / raw)
To: Paul Walmsley, Alexandre Ghiti, Palmer Dabbelt
Cc: Nick Desaulniers, Bill Wendling, Justin Stitt, Craig Topper,
linux-riscv, llvm, patches, Nathan Chancellor
After commit f6bff7827a48 ("riscv: uaccess: use 'asm_goto_output' for
get_user()"), which was the first commit that started using asm goto
with outputs on RISC-V, builds of clang built with assertions enabled
start crashing in certain files that use get_user() with:
clang: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:12743: Register FollowCopyChain(MachineRegisterInfo &, Register): Assertion `MI->getOpcode() == TargetOpcode::COPY && "start of copy chain MUST be COPY"' failed.
Internally, LLVM generates an addiw instruction when the output of the
inline asm (which may be any scalar type) needs to be sign extended for
ABI reasons, such as a later function call, so that basic block does not
have to do it.
Use a temporary 64-bit variable as the output of the inline assembly in
__get_user_asm() and explicitly cast it to truncate it if necessary,
avoiding the addiw that triggers the assertion.
Link: https://github.com/ClangBuiltLinux/linux/issues/2092
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
Changes in v2:
- Rebase on 6.19-rc5
- Send to updated addresses
- Link to v1: https://lore.kernel.org/r/20250811-riscv-wa-llvm-asm-goto-outputs-assertion-failure-v1-1-7bb8c9cbb92b@kernel.org
---
I did this unconditionally but I did not do much investigation into how
the code generation changes, as I never have good luck with figuring out
what is real vs. noise. If this is a worry, I can just duplicate this
under a CONFIG_CC_IS_CLANG block. Alternatively, we could mark
CONFIG_CC_HAS_ASM_GOTO_OUTPUT as broken with clang when targeting
RISC-V.
---
arch/riscv/include/asm/uaccess.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 36bba6720c26..2ccf93f746f0 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -98,12 +98,16 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigne
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
#define __get_user_asm(insn, x, ptr, label) \
+do { \
+ u64 __tmp; \
asm_goto_output( \
"1:\n" \
" " insn " %0, %1\n" \
_ASM_EXTABLE_UACCESS_ERR(1b, %l2, %0) \
- : "=&r" (x) \
- : "m" (*(ptr)) : : label)
+ : "=&r" (__tmp) \
+ : "m" (*(ptr)) : : label); \
+ (x) = (__typeof__(x))__tmp; \
+} while (0)
#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
#define __get_user_asm(insn, x, ptr, label) \
do { \
---
base-commit: 0f61b1860cc3f52aef9036d7235ed1f017632193
change-id: 20250811-riscv-wa-llvm-asm-goto-outputs-assertion-failure-6aefa26338cc
Best regards,
--
Nathan Chancellor <nathan@kernel.org>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH RFC v2] riscv: Use 64-bit variable for output in __get_user_asm
2026-01-14 0:09 [PATCH RFC v2] riscv: Use 64-bit variable for output in __get_user_asm Nathan Chancellor
@ 2026-01-15 1:02 ` Paul Walmsley
2026-01-16 5:10 ` Nathan Chancellor
0 siblings, 1 reply; 3+ messages in thread
From: Paul Walmsley @ 2026-01-15 1:02 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Paul Walmsley, Alexandre Ghiti, Palmer Dabbelt, Nick Desaulniers,
Bill Wendling, Justin Stitt, Craig Topper, linux-riscv, llvm,
patches
Hi Nathan,
On Tue, 13 Jan 2026, Nathan Chancellor wrote:
> After commit f6bff7827a48 ("riscv: uaccess: use 'asm_goto_output' for
> get_user()"), which was the first commit that started using asm goto
> with outputs on RISC-V, builds of clang built with assertions enabled
> start crashing in certain files that use get_user() with:
>
> clang: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:12743: Register FollowCopyChain(MachineRegisterInfo &, Register): Assertion `MI->getOpcode() == TargetOpcode::COPY && "start of copy chain MUST be COPY"' failed.
>
> Internally, LLVM generates an addiw instruction when the output of the
> inline asm (which may be any scalar type) needs to be sign extended for
> ABI reasons, such as a later function call, so that basic block does not
> have to do it.
>
> Use a temporary 64-bit variable as the output of the inline assembly in
> __get_user_asm() and explicitly cast it to truncate it if necessary,
> avoiding the addiw that triggers the assertion.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/2092
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> ---
> Changes in v2:
> - Rebase on 6.19-rc5
> - Send to updated addresses
> - Link to v1: https://lore.kernel.org/r/20250811-riscv-wa-llvm-asm-goto-outputs-assertion-failure-v1-1-7bb8c9cbb92b@kernel.org
> ---
> I did this unconditionally but I did not do much investigation into how
> the code generation changes, as I never have good luck with figuring out
> what is real vs. noise. If this is a worry, I can just duplicate this
> under a CONFIG_CC_IS_CLANG block. Alternatively, we could mark
> CONFIG_CC_HAS_ASM_GOTO_OUTPUT as broken with clang when targeting
> RISC-V.
I'm assuming this would be a temporary patch, and that we might be able to
remove it at some point (years, I guess?)
Might be worth adding a comment in the code to explain why a temporary
variable is needed.
thanks for the patch,
- Paul
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH RFC v2] riscv: Use 64-bit variable for output in __get_user_asm
2026-01-15 1:02 ` Paul Walmsley
@ 2026-01-16 5:10 ` Nathan Chancellor
0 siblings, 0 replies; 3+ messages in thread
From: Nathan Chancellor @ 2026-01-16 5:10 UTC (permalink / raw)
To: Paul Walmsley
Cc: Alexandre Ghiti, Palmer Dabbelt, Nick Desaulniers, Bill Wendling,
Justin Stitt, Craig Topper, linux-riscv, llvm, patches
On Wed, Jan 14, 2026 at 06:02:46PM -0700, Paul Walmsley wrote:
> I'm assuming this would be a temporary patch, and that we might be able to
> remove it at some point (years, I guess?)
Yes, ideally this would be short lived but unfortunately, I am not
really sure what the plan to fix this on the LLVM side is :/ Maybe Craig
or Bill can comment on that.
> Might be worth adding a comment in the code to explain why a temporary
> variable is needed.
I will insert:
/*
* Use a temporary variable for the output of the asm goto to avoid a
* triggering an LLVM assertion due to sign extending the output when
* it is used in function calls:
* https://github.com/llvm/llvm-project/issues/143795
*/
I will send v3 either tomorrow or Monday.
Cheers,
Nathan
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-01-16 5:10 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-14 0:09 [PATCH RFC v2] riscv: Use 64-bit variable for output in __get_user_asm Nathan Chancellor
2026-01-15 1:02 ` Paul Walmsley
2026-01-16 5:10 ` Nathan Chancellor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox