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;
// 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
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]