From 2388a096e7865c043e83ece4e26654bd3d1a20d5 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 29 May 2020 23:01:09 -0700 Subject: [PATCH 1/5] [lldb/Test] use GetLoadAddress from scripted thread plan Commit 0800529fe605 adds a runtime error which triggers when using SBAddress properties that use the current process/target from a non-interactive session. TestThreadPlanCommands.py was doing exactly this and this patch fixes that by use GetLoadAddress instead. --- .../API/functionalities/thread_plan/wrap_step_over.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py index a7b39764ceca0b..bce34d6916eec9 100644 --- a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py +++ b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py @@ -3,14 +3,16 @@ class WrapStepOver(): def __init__(self, thread_plan, args_data, dict): self.plan = thread_plan - frame_0 = thread_plan.GetThread().frames[0] + thread = thread_plan.GetThread() + target = thread.GetProcess().GetTarget() + frame_0 = thread.frames[0] line_entry = frame_0.line_entry start_addr = line_entry.addr end_addr = line_entry.end_addr - range_size = int(end_addr) - int(start_addr) + range_size = end_addr.GetLoadAddress(target) - start_addr.GetLoadAddress(target) error = lldb.SBError() self.sub_plan = thread_plan.QueueThreadPlanForStepOverRange(start_addr, range_size) - + def should_step(self): return False From cf97e0ec42b800ade5a18401a35ada96f355693f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 30 Apr 2019 11:50:09 +0300 Subject: [PATCH 2/5] [AArch64] Treat x18 as callee-saved in functions with windows calling convention on non-windows OSes Treat it as callee-saved, and always back it up. When windows code calls entry points in unix code, marked with the windows calling convention, that unix code can call other functions that isn't compiled with -ffixed-x18 which may clobber x18 freely. By backing it up and restoring it on return, we preserve the register across the function call, fulfilling this part of the windows calling convention on another OS. This isn't enough for making sure that x18 is preseved when non-windows code does a callback to windows code, but is a clear improvement over the current status quo. Additionally, wine is nowadays building many modules as PE DLLs, which avoids the callback issue altogether for those DLLs. Differential Revision: https://reviews.llvm.org/D61892 --- .../AArch64/AArch64CallingConvention.td | 4 +++ .../Target/AArch64/AArch64FrameLowering.cpp | 11 +++++++ .../Target/AArch64/AArch64ISelLowering.cpp | 7 +++++ .../Target/AArch64/AArch64RegisterInfo.cpp | 4 +++ .../CodeGen/AArch64/aarch64_win64cc_vararg.ll | 30 ++++++++++--------- .../CodeGen/AArch64/win64cc-backup-x18.ll | 26 ++++++++++++++++ 6 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/win64cc-backup-x18.ll diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td index eed87946dab9ee..a2219a240b9bcf 100644 --- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td +++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td @@ -384,6 +384,10 @@ def CSR_AArch64_AAPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24, D8, D9, D10, D11, D12, D13, D14, D15)>; +// A variant for treating X18 as callee saved, when interfacing with +// code that needs X18 to be preserved. +def CSR_AArch64_AAPCS_X18 : CalleeSavedRegs<(add X18, CSR_AArch64_AAPCS)>; + // Win64 has unwinding codes for an (FP,LR) pair, save_fplr and save_fplr_x. // We put FP before LR, so that frame lowering logic generates (FP,LR) pairs, // and not (LR,FP) pairs. diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 3abc03c0aaac3c..b42bd5769a99c7 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -2389,6 +2389,7 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); const AArch64RegisterInfo *RegInfo = static_cast( MF.getSubtarget().getRegisterInfo()); + const AArch64Subtarget &Subtarget = MF.getSubtarget(); AArch64FunctionInfo *AFI = MF.getInfo(); unsigned UnspilledCSGPR = AArch64::NoRegister; unsigned UnspilledCSGPRPaired = AArch64::NoRegister; @@ -2437,6 +2438,16 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, } } + if (MF.getFunction().getCallingConv() == CallingConv::Win64 && + !Subtarget.isTargetWindows()) { + // For Windows calling convention on a non-windows OS, where X18 is treated + // as reserved, back up X18 when entering non-windows code (marked with the + // Windows calling convention) and restore when returning regardless of + // whether the individual function uses it - it might call other functions + // that clobber it. + SavedRegs.set(AArch64::X18); + } + // Calculates the callee saved stack size. unsigned CSStackSize = 0; unsigned SVECSStackSize = 0; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index dfa4b493c22168..6e708f5ea7169d 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3958,6 +3958,13 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization( CallingConv::ID CallerCC = CallerF.getCallingConv(); bool CCMatch = CallerCC == CalleeCC; + // When using the Windows calling convention on a non-windows OS, we want + // to back up and restore X18 in such functions; we can't do a tail call + // from those functions. + if (CallerCC == CallingConv::Win64 && !Subtarget->isTargetWindows() && + CalleeCC != CallingConv::Win64) + return false; + // Byval parameters hand the function a pointer directly into the stack area // we want to reuse during a tail call. Working around this *is* possible (see // X86) but less efficient and uglier in LowerCall. diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index f33695e5ac5209..886158ca449018 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -71,6 +71,10 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CSR_AArch64_AAPCS_SwiftError_SaveList; if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost) return CSR_AArch64_RT_MostRegs_SaveList; + if (MF->getFunction().getCallingConv() == CallingConv::Win64) + // This is for OSes other than Windows; Windows is a separate case further + // above. + return CSR_AArch64_AAPCS_X18_SaveList; return CSR_AArch64_AAPCS_SaveList; } diff --git a/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll b/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll index a45ae74ac49b94..41623297848624 100644 --- a/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll +++ b/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll @@ -2,16 +2,18 @@ define win64cc void @pass_va(i32 %count, ...) nounwind { entry: -; CHECK: str x30, [sp, #-80]! -; CHECK: add x8, sp, #24 -; CHECK: add x0, sp, #24 -; CHECK: stp x1, x2, [sp, #24] -; CHECK: stp x3, x4, [sp, #40] -; CHECK: stp x5, x6, [sp, #56] -; CHECK: str x7, [sp, #72] +; CHECK: sub sp, sp, #96 +; CHECK: add x8, sp, #40 +; CHECK: add x0, sp, #40 +; CHECK: stp x30, x18, [sp, #16] +; CHECK: stp x1, x2, [sp, #40] +; CHECK: stp x3, x4, [sp, #56] +; CHECK: stp x5, x6, [sp, #72] +; CHECK: str x7, [sp, #88] ; CHECK: str x8, [sp, #8] ; CHECK: bl other_func -; CHECK: ldr x30, [sp], #80 +; CHECK: ldp x30, x18, [sp, #16] +; CHECK: add sp, sp, #96 ; CHECK: ret %ap = alloca i8*, align 8 %ap1 = bitcast i8** %ap to i8* @@ -27,11 +29,11 @@ declare void @llvm.va_start(i8*) nounwind declare void @llvm.va_copy(i8*, i8*) nounwind ; CHECK-LABEL: f9: -; CHECK: sub sp, sp, #16 +; CHECK: str x18, [sp, #-16]! ; CHECK: add x8, sp, #24 ; CHECK: add x0, sp, #24 ; CHECK: str x8, [sp, #8] -; CHECK: add sp, sp, #16 +; CHECK: ldr x18, [sp], #16 ; CHECK: ret define win64cc i8* @f9(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, ...) nounwind { entry: @@ -43,11 +45,11 @@ entry: } ; CHECK-LABEL: f8: -; CHECK: sub sp, sp, #16 +; CHECK: str x18, [sp, #-16]! ; CHECK: add x8, sp, #16 ; CHECK: add x0, sp, #16 ; CHECK: str x8, [sp, #8] -; CHECK: add sp, sp, #16 +; CHECK: ldr x18, [sp], #16 ; CHECK: ret define win64cc i8* @f8(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, ...) nounwind { entry: @@ -59,12 +61,12 @@ entry: } ; CHECK-LABEL: f7: -; CHECK: sub sp, sp, #32 +; CHECK: str x18, [sp, #-32]! ; CHECK: add x8, sp, #24 ; CHECK: str x7, [sp, #24] ; CHECK: add x0, sp, #24 ; CHECK: str x8, [sp, #8] -; CHECK: add sp, sp, #32 +; CHECK: ldr x18, [sp], #32 ; CHECK: ret define win64cc i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind { entry: diff --git a/llvm/test/CodeGen/AArch64/win64cc-backup-x18.ll b/llvm/test/CodeGen/AArch64/win64cc-backup-x18.ll new file mode 100644 index 00000000000000..936ee3ca9e3928 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/win64cc-backup-x18.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +;; Testing that x18 is backed up and restored, and that x29 (if used) still +;; points to the x29,x30 pair on the stack. + +; RUN: llc < %s -mtriple=aarch64-linux-gnu --frame-pointer=non-leaf | FileCheck %s +; RUN: llc < %s -mtriple=aarch64-linux-gnu --frame-pointer=non-leaf -mattr=+reserve-x18 | FileCheck %s + +declare dso_local void @other() + +define dso_local win64cc void @func() #0 { +; CHECK-LABEL: func: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: stp x29, x30, [sp, #-32]! // 16-byte Folded Spill +; CHECK-NEXT: str x18, [sp, #16] // 8-byte Folded Spill +; CHECK-NEXT: mov x29, sp +; CHECK-NEXT: bl other +; CHECK-NEXT: ldr x18, [sp, #16] // 8-byte Folded Reload +; CHECK-NEXT: ldp x29, x30, [sp], #32 // 16-byte Folded Reload +; CHECK-NEXT: ret +entry: + tail call void @other() + ret void +} + +attributes #0 = { nounwind } From 51089db6d7554cefc6c57e6f10a7f876e2dd629e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 30 May 2020 01:20:14 +0300 Subject: [PATCH 3/5] [test] Regenerate checks in aarch64_win64cc_vararg.ll with update_llc_test_checks.py. NFC. --- .../CodeGen/AArch64/aarch64_win64cc_vararg.ll | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll b/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll index 41623297848624..fe1a1f0e58136b 100644 --- a/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll +++ b/llvm/test/CodeGen/AArch64/aarch64_win64cc_vararg.ll @@ -1,20 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s define win64cc void @pass_va(i32 %count, ...) nounwind { +; CHECK-LABEL: pass_va: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sub sp, sp, #96 // =96 +; CHECK-NEXT: add x8, sp, #40 // =40 +; CHECK-NEXT: add x0, sp, #40 // =40 +; CHECK-NEXT: stp x30, x18, [sp, #16] // 16-byte Folded Spill +; CHECK-NEXT: stp x1, x2, [sp, #40] +; CHECK-NEXT: stp x3, x4, [sp, #56] +; CHECK-NEXT: stp x5, x6, [sp, #72] +; CHECK-NEXT: str x7, [sp, #88] +; CHECK-NEXT: str x8, [sp, #8] +; CHECK-NEXT: bl other_func +; CHECK-NEXT: ldp x30, x18, [sp, #16] // 16-byte Folded Reload +; CHECK-NEXT: add sp, sp, #96 // =96 +; CHECK-NEXT: ret entry: -; CHECK: sub sp, sp, #96 -; CHECK: add x8, sp, #40 -; CHECK: add x0, sp, #40 -; CHECK: stp x30, x18, [sp, #16] -; CHECK: stp x1, x2, [sp, #40] -; CHECK: stp x3, x4, [sp, #56] -; CHECK: stp x5, x6, [sp, #72] -; CHECK: str x7, [sp, #88] -; CHECK: str x8, [sp, #8] -; CHECK: bl other_func -; CHECK: ldp x30, x18, [sp, #16] -; CHECK: add sp, sp, #96 -; CHECK: ret %ap = alloca i8*, align 8 %ap1 = bitcast i8** %ap to i8* call void @llvm.va_start(i8* %ap1) @@ -28,14 +31,15 @@ declare void @other_func(i8*) local_unnamed_addr declare void @llvm.va_start(i8*) nounwind declare void @llvm.va_copy(i8*, i8*) nounwind -; CHECK-LABEL: f9: -; CHECK: str x18, [sp, #-16]! -; CHECK: add x8, sp, #24 -; CHECK: add x0, sp, #24 -; CHECK: str x8, [sp, #8] -; CHECK: ldr x18, [sp], #16 -; CHECK: ret define win64cc i8* @f9(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, ...) nounwind { +; CHECK-LABEL: f9: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x18, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: add x8, sp, #24 // =24 +; CHECK-NEXT: add x0, sp, #24 // =24 +; CHECK-NEXT: str x8, [sp, #8] +; CHECK-NEXT: ldr x18, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret entry: %ap = alloca i8*, align 8 %ap1 = bitcast i8** %ap to i8* @@ -44,14 +48,15 @@ entry: ret i8* %ap2 } -; CHECK-LABEL: f8: -; CHECK: str x18, [sp, #-16]! -; CHECK: add x8, sp, #16 -; CHECK: add x0, sp, #16 -; CHECK: str x8, [sp, #8] -; CHECK: ldr x18, [sp], #16 -; CHECK: ret define win64cc i8* @f8(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, ...) nounwind { +; CHECK-LABEL: f8: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x18, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: add x8, sp, #16 // =16 +; CHECK-NEXT: add x0, sp, #16 // =16 +; CHECK-NEXT: str x8, [sp, #8] +; CHECK-NEXT: ldr x18, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret entry: %ap = alloca i8*, align 8 %ap1 = bitcast i8** %ap to i8* @@ -60,15 +65,16 @@ entry: ret i8* %ap2 } -; CHECK-LABEL: f7: -; CHECK: str x18, [sp, #-32]! -; CHECK: add x8, sp, #24 -; CHECK: str x7, [sp, #24] -; CHECK: add x0, sp, #24 -; CHECK: str x8, [sp, #8] -; CHECK: ldr x18, [sp], #32 -; CHECK: ret define win64cc i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind { +; CHECK-LABEL: f7: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: str x18, [sp, #-32]! // 8-byte Folded Spill +; CHECK-NEXT: add x8, sp, #24 // =24 +; CHECK-NEXT: str x7, [sp, #24] +; CHECK-NEXT: add x0, sp, #24 // =24 +; CHECK-NEXT: str x8, [sp, #8] +; CHECK-NEXT: ldr x18, [sp], #32 // 8-byte Folded Reload +; CHECK-NEXT: ret entry: %ap = alloca i8*, align 8 %ap1 = bitcast i8** %ap to i8* From c65c1d78931e262b5117278a8ee0a703d1be073c Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 29 May 2020 22:46:57 -0700 Subject: [PATCH 4/5] [X86] Autogenerate complete checks. NFC --- llvm/test/CodeGen/X86/i1narrowfail.ll | 7 +++++-- llvm/test/CodeGen/X86/narrow_op-1.ll | 15 +++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/llvm/test/CodeGen/X86/i1narrowfail.ll b/llvm/test/CodeGen/X86/i1narrowfail.ll index 4f9a75672bfc63..282d1ac28f5962 100644 --- a/llvm/test/CodeGen/X86/i1narrowfail.ll +++ b/llvm/test/CodeGen/X86/i1narrowfail.ll @@ -1,8 +1,11 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl | FileCheck %s -; CHECK-LABEL: @foo -; CHECK: orb $16 define void @foo(i64* %ptr) { +; CHECK-LABEL: foo: +; CHECK: ## %bb.0: +; CHECK-NEXT: orb $16, (%rdi) +; CHECK-NEXT: retq %r11 = load i64, i64* %ptr, align 8 %r12 = or i64 16, %r11 store i64 %r12, i64* %ptr, align 8 diff --git a/llvm/test/CodeGen/X86/narrow_op-1.ll b/llvm/test/CodeGen/X86/narrow_op-1.ll index 96751abde28daf..dc24b190ea9139 100644 --- a/llvm/test/CodeGen/X86/narrow_op-1.ll +++ b/llvm/test/CodeGen/X86/narrow_op-1.ll @@ -1,28 +1,31 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s %struct.bf = type { i64, i16, i16, i32 } @bfi = common global %struct.bf zeroinitializer, align 16 define void @t1() nounwind optsize ssp { +; CHECK-LABEL: t1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: orb $1, bfi+{{.*}}(%rip) +; CHECK-NEXT: retq entry: %0 = load i32, i32* bitcast (i16* getelementptr (%struct.bf, %struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 %1 = or i32 %0, 65536 store i32 %1, i32* bitcast (i16* getelementptr (%struct.bf, %struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 ret void -; CHECK-LABEL: t1: -; CHECK: orb $1 -; CHECK-NEXT: ret } define void @t2() nounwind optsize ssp { +; CHECK-LABEL: t2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: orl $16842752, bfi+{{.*}}(%rip) # imm = 0x1010000 +; CHECK-NEXT: retq entry: %0 = load i32, i32* bitcast (i16* getelementptr (%struct.bf, %struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 %1 = or i32 %0, 16842752 store i32 %1, i32* bitcast (i16* getelementptr (%struct.bf, %struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 ret void -; CHECK-LABEL: t2: -; CHECK: orl $16842752 -; CHECK-NEXT: ret } From 92063228f85bfe22a6dfe20bf01c99ffe6ff3130 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 29 May 2020 23:50:26 -0700 Subject: [PATCH 5/5] [lldb/CMake] Fix typo that prevented regenerating the bindings A typo in the GLOB patter prevented us from detecting changes in the interface files and trigger SWIG to regenerate the bindings. --- lldb/bindings/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/bindings/CMakeLists.txt b/lldb/bindings/CMakeLists.txt index 92ae402c478e94..ace34191a3c575 100644 --- a/lldb/bindings/CMakeLists.txt +++ b/lldb/bindings/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB SWIG_INTERFACES interfaces/*.i) +file(GLOB SWIG_INTERFACES interface/*.i) file(GLOB_RECURSE SWIG_SOURCES *.swig) file(GLOB SWIG_HEADERS ${LLDB_SOURCE_DIR}/include/lldb/API/*.h