Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ 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`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks as if this is specifically referring to inline asm?

I looked at the PR title and thought "Surely LLVM already knows that r14 means lr?" And in some contexts it has no trouble with it:

$ llvm-mc -triple armv7a -show-encoding <<< "bx r14"
        bx      lr                              @ encoding: [0x1e,0xff,0x2f,0xe1]

So this wording probably wants to be more specific, to avoid giving the impression that the missing feature was bigger than it was!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, fixed

Clang always canonicalizes the name to `lr`, but other frontends may not.

Changes to the AVR Backend
--------------------------

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/CodeGen/ARM/inline-asm-clobber.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}