diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -860,6 +860,16 @@ if (Nops != 0 && Nops != 4) return false; int H = Nops == 4; + // There's an inconsistency regarding packed unwind info with homed + // parameters; according to the documentation, the epilog shouldn't have + // the same corresponding nops (and thus, to set the H bit, we should + // require an epilog which isn't exactly symmetrical - we shouldn't accept + // an exact mirrored epilog for those cases), but in practice, + // RtlVirtualUnwind behaves as if it does expect the epilogue to contain + // the same nops. See https://github.com/llvm/llvm-project/issues/54879. + // To play it safe, don't produce packed unwind info with homed parameters. + if (H) + return false; int IntSZ = 8 * RegI; if (StandaloneLR) IntSZ += 8; diff --git a/llvm/test/MC/AArch64/seh-packed-unwind.s b/llvm/test/MC/AArch64/seh-packed-unwind.s --- a/llvm/test/MC/AArch64/seh-packed-unwind.s +++ b/llvm/test/MC/AArch64/seh-packed-unwind.s @@ -81,25 +81,10 @@ // CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: RuntimeFunction { -// CHECK-NEXT: Function: func5 -// CHECK-NEXT: Fragment: No -// CHECK-NEXT: FunctionLength: 56 -// CHECK-NEXT: RegF: 0 -// CHECK-NEXT: RegI: 1 -// CHECK-NEXT: HomedParameters: Yes -// CHECK-NEXT: CR: 0 -// CHECK-NEXT: FrameSize: 112 -// CHECK-NEXT: Prologue [ -// CHECK-NEXT: sub sp, sp, #32 -// CHECK-NEXT: stp x6, x7, [sp, #64] -// CHECK-NEXT: stp x4, x5, [sp, #48] -// CHECK-NEXT: stp x2, x3, [sp, #32] -// CHECK-NEXT: stp x0, x1, [sp, #16] -// CHECK-NEXT: str x19, [sp, #-80]! -// CHECK-NEXT: end -// CHECK-NEXT: ] -// CHECK-NEXT: } -// CHECK-NEXT: RuntimeFunction { +// CHECK-NEXT: Function: notpacked_func5 +// CHECK-NEXT: ExceptionRecord: +// CHECK-NEXT: ExceptionData { +// CHECK: RuntimeFunction { // CHECK-NEXT: Function: func6 // CHECK-NEXT: Fragment: No // CHECK-NEXT: FunctionLength: 24 @@ -441,8 +426,8 @@ ret .seh_endproc -func5: - .seh_proc func5 +notpacked_func5: + .seh_proc notpacked_func5 str x19, [sp, #-80]! .seh_save_reg_x x19, 80 stp x0, x1, [sp, #16]