https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/228699
Backport b028ea8 Requested by: @folkertdev >From b3c1ada9ccd149fe234c0484cbbe277339641f00 Mon Sep 17 00:00:00 2001 From: Folkert de Vries <[email protected]> Date: Sat, 3 Oct 2026 13:41:57 +0200 Subject: [PATCH] [ARM] fix `r14` aliasing `lr` on `thumb-1` (#225746) Since https://github.com/llvm/llvm-project/pull/179740 `r14` is accepted as an alias for `lr`, which works on `arm` and `thumb-2` targets, but not on `thumb-1` https://godbolt.org/z/WEEjMMj93 ```llvm ; -mtriple=thumbv6m-none-eabi define i32 @read_r14() nounwind { start: %1 = tail call i32 asm sideeffect alignstack "", "=&{r14},~{cc},~{memory}"() ret i32 %1 } ``` Gives ``` error: register 'LR' allocated for constraint '{r14}' does not match required type ``` Apparently on `thumb-1` the register class of `lr` is not the same as the class of `i32`. So, just truly make `{r14}` an alias for `{lr}`. --- Found via https://github.com/rust-lang/rust/issues/163173. We should backport this if we can. (cherry picked from commit b028ea82203a25d29bf469286319a0e7b3daa1d5) --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 2 +- llvm/test/CodeGen/ARM/inline-asm-clobber.ll | 50 ++++++++++++++------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 998e09384dab6c..16f1d3c7fc6264 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -20670,7 +20670,7 @@ RCPair ARMTargetLowering::getRegForInlineAsmConstraint( // r14 is an alias of lr. if (StringRef("{r14}").equals_insensitive(Constraint)) - return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32)); + Constraint = "{lr}"; auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); if (isIncompatibleReg(RCP.first, VT)) diff --git a/llvm/test/CodeGen/ARM/inline-asm-clobber.ll b/llvm/test/CodeGen/ARM/inline-asm-clobber.ll index cb84fa4fd032ae..4260b625c95b12 100644 --- a/llvm/test/CodeGen/ARM/inline-asm-clobber.ll +++ b/llvm/test/CodeGen/ARM/inline-asm-clobber.ll @@ -1,4 +1,4 @@ -; RUN: llc <%s -mtriple=arm-none-eabi 2>&1 | FileCheck %s -check-prefix=CHECK +; RUN: llc <%s -mtriple=arm-none-eabi 2>&1 | FileCheck %s -check-prefix=ARM_NONE ; RUN: llc <%s -mtriple=arm-none-eabi -relocation-model=rwpi 2>&1 \ ; RUN: | FileCheck %s -check-prefix=RWPI @@ -11,36 +11,46 @@ ; RUN: llc <%s -mtriple=armv6k-apple-ios3 2>&1 | FileCheck %s -check-prefix=IOS3 ; RUN: llc <%s -mtriple=armv7-apple-ios2 2>&1 | FileCheck %s -check-prefix=IOS3 -; CHECK: warning: inline asm clobber list contains reserved registers: SP, PC -; CHECK: warning: inline asm clobber list contains reserved registers: R11 +; RUN: llc <%s -mtriple=thumbv6m-none-eabi 2>&1 | FileCheck %s -check-prefix=THUMB +; RUN: llc <%s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s -check-prefix=THUMB +; RUN: llc <%s -mtriple=thumbv7m-none-eabi 2>&1 | FileCheck %s -check-prefix=THUMB + +; ARM_NONE: warning: inline asm clobber list contains reserved registers: SP, PC +; ARM_NONE: warning: inline asm clobber list contains reserved registers: R11 ; RWPI: warning: inline asm clobber list contains reserved registers: R9, SP, PC ; RWPI: warning: inline asm clobber list contains reserved registers: R11 ; NO_FP_ELIM: warning: inline asm clobber list contains reserved registers: R11, SP, PC ; NO_FP_ELIM: warning: inline asm clobber list contains reserved registers: R11 ; IOS2: warning: inline asm clobber list contains reserved registers: R9, SP, PC ; IOS3: warning: inline asm clobber list contains reserved registers: SP, PC +; THUMB: warning: inline asm clobber list contains reserved registers: SP, PC define void @foo() nounwind { - call void asm sideeffect "mov r7, #1", + call void asm sideeffect "movs r7, #1", "~{r9},~{r11},~{r12},~{lr},~{sp},~{pc},~{r10}"() ret void } define i32 @bar(i32 %i) { %vla = alloca i32, i32 %i, align 4 - tail call void asm sideeffect "mov r7, #1", "~{r11}"() + tail call void asm sideeffect "movs r7, #1", "~{r11}"() %1 = load volatile i32, ptr %vla, align 4 ret i32 %1 } ; r14 is an alias for lr. define void @clobber_r14() nounwind { -; CHECK-LABEL: clobber_r14: -; CHECK: .save {r11, lr} -; CHECK: push {r11, lr} -; CHECK-NEXT: @APP -; CHECK-NEXT: @NO_APP -; CHECK-NEXT: pop {r11, lr} +; ARM_NONE-LABEL: clobber_r14: +; ARM_NONE: .save {r11, lr} +; ARM_NONE: push {r11, lr} +; ARM_NONE-NEXT: @APP +; ARM_NONE-NEXT: @NO_APP +; ARM_NONE-NEXT: pop {r11, lr} +; THUMB-LABEL: clobber_r14: +; THUMB: push {r7, lr} +; THUMB-NEXT: @APP +; THUMB-NEXT: @NO_APP +; THUMB-NEXT: pop {r7, pc} tail call void asm sideeffect "", "~{r14}"() ret void } @@ -48,12 +58,18 @@ define void @clobber_r14() nounwind { ; r14 is an alias for lr. define i32 @read_r14() nounwind { start: -; CHECK-LABEL: read_r14: -; CHECK: push {r11, lr} -; CHECK-NEXT: @APP -; CHECK-NEXT: @NO_APP -; CHECK-NEXT: mov r0, lr -; CHECK-NEXT: pop {r11, lr} +; ARM_NONE-LABEL: read_r14: +; ARM_NONE: push {r11, lr} +; ARM_NONE-NEXT: @APP +; ARM_NONE-NEXT: @NO_APP +; ARM_NONE-NEXT: mov r0, lr +; ARM_NONE-NEXT: pop {r11, lr} +; THUMB-LABEL: read_r14: +; THUMB: push {r7, lr} +; THUMB-NEXT: @APP +; THUMB-NEXT: @NO_APP +; THUMB-NEXT: mov r0, lr +; THUMB-NEXT: pop {r7, pc} %1 = tail call i32 asm sideeffect alignstack "", "=&{r14},~{cc},~{memory}"() ret i32 %1 } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
