Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2744,15 +2744,13 @@ Op.getOperand(1), Op.getOperand(2)); case Intrinsic::localaddress: { - // Returns one of the stack, base, or frame pointer registers, depending on - // which is used to reference local variables. - MachineFunction &MF = DAG.getMachineFunction(); - const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo(); - unsigned Reg; - if (RegInfo->hasBasePointer(MF)) - Reg = RegInfo->getBaseRegister(); - else // This function handles the SP or FP case. - Reg = RegInfo->getFrameRegister(MF); + auto &MF = DAG.getMachineFunction(); + const auto *RegInfo = Subtarget->getRegisterInfo(); + + auto Reg = RegInfo->needsStackRealignment(MF) ? + RegInfo->getBaseRegister() : + RegInfo->getFrameRegister(MF); + return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, Op.getSimpleValueType()); } Index: test/CodeGen/AArch64/seh-localaddress.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/seh-localaddress.ll @@ -0,0 +1,55 @@ +; RUN: llc -mtriple arm64-windows -o - %s | FileCheck %s + +; struct S { int x; }; +; void foo() { +; struct S __declspec(align(32)) o; +; __try { o.x; } +; __finally { o.x; } +; } +; void bar() { +; struct S o; +; __try { o.x; } +; __finally { o.x; } +; } + +%struct.S = type { i32 } + +define dso_local void @"?foo@@YAXXZ"() #0 { +entry: +; CHECK-LABEL: foo +; CHECK: mov x1, x19 +; CHECK-NOT: mov x1, x29 + + %o = alloca %struct.S, align 32 + call void (...) @llvm.localescape(%struct.S* %o) + %x = getelementptr inbounds %struct.S, %struct.S* %o, i32 0, i32 0 + %0 = call i8* @llvm.localaddress() + call void @"?fin$0@0@foo@@"(i8 0, i8* %0) + ret void +} + +define dso_local void @"?bar@@YAXXZ"() { +entry: +; CHECK-LABEL: bar +; CHECK: mov x1, x29 +; CHECK-NOT: mov x1, x19 + + %o = alloca %struct.S, align 4 + call void (...) @llvm.localescape(%struct.S* %o) + %x = getelementptr inbounds %struct.S, %struct.S* %o, i32 0, i32 0 + %0 = call i8* @llvm.localaddress() + call void @"?fin$0@0@bar@@"(i8 0, i8* %0) + ret void +} + +declare void @"?fin$0@0@foo@@"(i8 %abnormal_termination, i8* %frame_pointer) + +declare void @"?fin$0@0@bar@@"(i8 %abnormal_termination, i8* %frame_pointer) + +declare i8* @llvm.localrecover(i8*, i8*, i32) + +declare i8* @llvm.localaddress() + +declare void @llvm.localescape(...) + +attributes #0 = { noinline optnone uwtable }