diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -4666,11 +4666,13 @@ } MFI.setReturnAddressIsTaken(true); MF.addLiveIn(AArch64::LR, &AArch64::GPR64spRegClass); - I.getParent()->addLiveIn(AArch64::LR); // Insert the copy from LR/X30 into the entry block, before it can be // clobbered by anything. + MachineBasicBlock &EntryBlock = *MF.begin(); + if (!EntryBlock.isLiveIn(AArch64::LR)) + EntryBlock.addLiveIn(AArch64::LR); MachineIRBuilder EntryBuilder(MF); - EntryBuilder.setInstr(*MF.begin()->begin()); + EntryBuilder.setInstr(*EntryBlock.begin()); EntryBuilder.buildCopy({DstReg}, {Register(AArch64::LR)}); MFReturnAddr = DstReg; I.eraseFromParent(); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-returnaddress-liveins.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-returnaddress-liveins.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-returnaddress-liveins.mir @@ -0,0 +1,61 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=aarch64 -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s + +--- | + define void @lr_other_block() { ret void } + define void @already_live_in() { ret void } + declare i8* @llvm.returnaddress(i32 immarg) +... +--- +name: lr_other_block +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: lr_other_block + ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x80000000) + ; CHECK: liveins: $w0, $x0, $lr + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $lr + ; CHECK: B %bb.1 + ; CHECK: bb.1: + ; CHECK: $x0 = COPY [[COPY]] + ; CHECK: RET_ReallyLR implicit $x0 + ; LR should be added as a livein to the entry block. + + bb.0: + ; We should have lr as a livein to bb.0, and a copy from LR. + liveins: $w0, $x0 + G_BR %bb.1 + bb.1: + %4:gpr(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0 + $x0 = COPY %4 + RET_ReallyLR implicit $x0 +... +--- +name: already_live_in +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: already_live_in + ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x80000000) + ; CHECK: liveins: $w0, $x0, $lr + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $lr + ; CHECK: B %bb.1 + ; CHECK: bb.1: + ; CHECK: $x0 = COPY [[COPY]] + ; CHECK: RET_ReallyLR implicit $x0 + ; We should not have LR listed as a livein twice. + + bb.0: + liveins: $w0, $x0, $lr + G_BR %bb.1 + bb.1: + %4:gpr(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0 + $x0 = COPY %4 + RET_ReallyLR implicit $x0 +...