[llvm] 1cc8fff - [AArch64] Fix save register pairing for Windows AAPCS

Sanne Wouda via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 14 07:08:50 PST 2020


Author: Sanne Wouda
Date: 2020-01-14T15:08:27Z
New Revision: 1cc8fff420a76ae869f73ce2b19e7c1fc73da3ed

URL: https://github.com/llvm/llvm-project/commit/1cc8fff420a76ae869f73ce2b19e7c1fc73da3ed
DIFF: https://github.com/llvm/llvm-project/commit/1cc8fff420a76ae869f73ce2b19e7c1fc73da3ed.diff

LOG: [AArch64] Fix save register pairing for Windows AAPCS

Summary:
On Windows, when a function does not have an unwind table (for example, EH
filtering funclets), we don't correctly pair FP and LR to form the frame record
in all circumstances.

Fix this by invalidating a pair when the second register is FP when compiling
for Windows, even when CFI is not needed.

Fixes PR44271 introduced by D65653.

Reviewers: efriedma, sdesmalen, rovka, rengolin, t.p.northover, thegameg, greened

Reviewed By: rengolin

Subscribers: kristof.beyls, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71754

Added: 
    llvm/test/CodeGen/AArch64/win64-no-uwtable.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 7575d1a25e58..ea3e800a1ad2 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -836,6 +836,10 @@ static bool isTargetDarwin(const MachineFunction &MF) {
   return MF.getSubtarget<AArch64Subtarget>().isTargetDarwin();
 }
 
+static bool isTargetWindows(const MachineFunction &MF) {
+  return MF.getSubtarget<AArch64Subtarget>().isTargetWindows();
+}
+
 // Convenience function to determine whether I is an SVE callee save.
 static bool IsSVECalleeSave(MachineBasicBlock::iterator I) {
   switch (I->getOpcode()) {
@@ -1870,6 +1874,8 @@ static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
 
   // TODO: LR can be paired with any register.  We don't support this yet in
   // the MCLayer.  We need to add support for the save_lrpair unwind code.
+  if (Reg2 == AArch64::FP)
+    return true;
   if (!NeedsWinCFI)
     return false;
   if (Reg2 == Reg1 + 1)
@@ -1882,9 +1888,9 @@ static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
 /// LR and FP need to be allocated together when the frame needs to save
 /// the frame-record. This means any other register pairing with LR is invalid.
 static bool invalidateRegisterPairing(unsigned Reg1, unsigned Reg2,
-                                      bool NeedsWinCFI, bool NeedsFrameRecord) {
-  if (NeedsWinCFI)
-    return invalidateWindowsRegisterPairing(Reg1, Reg2, true);
+                                      bool UsesWinAAPCS, bool NeedsWinCFI, bool NeedsFrameRecord) {
+  if (UsesWinAAPCS)
+    return invalidateWindowsRegisterPairing(Reg1, Reg2, NeedsWinCFI);
 
   // If we need to store the frame record, don't pair any register
   // with LR other than FP.
@@ -1934,6 +1940,7 @@ static void computeCalleeSaveRegisterPairs(
   if (CSI.empty())
     return;
 
+  bool IsWindows = isTargetWindows(MF);
   bool NeedsWinCFI = needsWinCFI(MF);
   AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
   MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -1976,7 +1983,7 @@ static void computeCalleeSaveRegisterPairs(
       switch (RPI.Type) {
       case RegPairInfo::GPR:
         if (AArch64::GPR64RegClass.contains(NextReg) &&
-            !invalidateRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI,
+            !invalidateRegisterPairing(RPI.Reg1, NextReg, IsWindows, NeedsWinCFI,
                                        NeedsFrameRecord))
           RPI.Reg2 = NextReg;
         break;
@@ -2018,6 +2025,11 @@ static void computeCalleeSaveRegisterPairs(
             RPI.Reg1 == AArch64::LR) &&
            "FrameRecord must be allocated together with LR");
 
+    // Windows AAPCS has FP and LR reversed.
+    assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg1 != AArch64::FP ||
+            RPI.Reg2 == AArch64::LR) &&
+           "FrameRecord must be allocated together with LR");
+
     // MachO's compact unwind format relies on all registers being stored in
     // adjacent register pairs.
     assert((!produceCompactUnwindFrame(MF) ||

diff  --git a/llvm/test/CodeGen/AArch64/win64-no-uwtable.ll b/llvm/test/CodeGen/AArch64/win64-no-uwtable.ll
new file mode 100644
index 000000000000..f04a47cd1e44
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/win64-no-uwtable.ll
@@ -0,0 +1,35 @@
+; RUN: llc -mtriple=arm64-windows -o - %s | FileCheck %s
+
+declare void @f()
+declare void @g()
+
+; Function Attrs: nounwind
+define dso_local void @SEHfilter() nounwind "frame-pointer"="all" {
+; CHECK-LABEL: @SEHfilter
+; CHECK:       %bb.0:
+; CHECK-NEXT:  stp     x30, x29, [sp, #-32]!
+; CHECK-NEXT:  str     x19, [sp, #16]
+; CHECK-NEXT:  ldr     w19, [x8]
+; CHECK-NEXT:  mov     x29, sp
+; CHECK-NEXT:  bl      g
+; CHECK-NEXT:  cbz     w19, .LBB0_2
+; CHECK-NEXT:  ; %bb.1:
+; CHECK-NEXT:  ldr     x19, [sp, #16]
+; CHECK-NEXT:  ldp     x30, x29, [sp], #32
+; CHECK-NEXT:  ret
+; CHECK-NEXT:  .LBB0_2:                                ; %if.end.i
+; CHECK-NEXT:  bl      f
+; CHECK-NEXT:  brk     #0x1
+  %1 = load i32, i32* undef, align 4
+  tail call void @g()
+  %tobool.i = icmp eq i32 %1, 0
+  br i1 %tobool.i, label %if.end.i, label %exit
+
+if.end.i:
+  call void @f()
+  unreachable
+
+exit:
+  ret void
+}
+


        


More information about the llvm-commits mailing list