diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index c3ff79e5422ab..a2202140e67f7 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -91,6 +91,10 @@ Changes to the AMDGPU Backend Changes to the ARM Backend -------------------------- +* The `r14` register can now be used as an alias for the link register `lr` + in inline assembly. Clang always canonicalizes the name to `lr`, but other + frontends may not. + Changes to the AVR Backend -------------------------- diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 7b240462c66fb..4b3e0a8546b09 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -20162,6 +20162,10 @@ RCPair ARMTargetLowering::getRegForInlineAsmConstraint( if (StringRef("{cc}").equals_insensitive(Constraint)) return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass); + // r14 is an alias of lr. + if (StringRef("{r14}").equals_insensitive(Constraint)) + return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32)); + auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); if (isIncompatibleReg(RCP.first, VT)) return {0, nullptr}; diff --git a/llvm/test/CodeGen/ARM/inline-asm-clobber.ll b/llvm/test/CodeGen/ARM/inline-asm-clobber.ll index f44ad2a896ad4..cb84fa4fd032a 100644 --- a/llvm/test/CodeGen/ARM/inline-asm-clobber.ll +++ b/llvm/test/CodeGen/ARM/inline-asm-clobber.ll @@ -32,3 +32,28 @@ define i32 @bar(i32 %i) { %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} + tail call void asm sideeffect "", "~{r14}"() + ret void +} + +; 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} + %1 = tail call i32 asm sideeffect alignstack "", "=&{r14},~{cc},~{memory}"() + ret i32 %1 +}