diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h index ca8b786f4ab69..ae580520b9110 100644 --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -1663,7 +1663,11 @@ class BinaryFunction { Offset = I->first; } assert(I->first == Offset && "CFI pointing to unknown instruction"); - if (I == Instructions.begin()) { + // When dealing with RememberState, we place this CFI in FrameInstructions. + // We want to ensure RememberState and RestoreState CFIs are in the same + // list in order to properly populate the StateStack. + if (I == Instructions.begin() && + Inst.getOperation() != MCCFIInstruction::OpRememberState) { CIEFrameInstructions.emplace_back(std::forward(Inst)); return; } diff --git a/bolt/test/AArch64/cfi-state-list.test b/bolt/test/AArch64/cfi-state-list.test new file mode 100644 index 0000000000000..2109f912ce890 --- /dev/null +++ b/bolt/test/AArch64/cfi-state-list.test @@ -0,0 +1,34 @@ +// This test checks that BOLT does not split remember and restore CFI states +// into different lists, which would cause an assertion failure. + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s + +# CHECK: BOLT-INFO: Starting stub-insertion pass + +.text +.global main +.type main, %function + +main: +.cfi_startproc +.cfi_remember_state + mov w0, wzr + b.ne .L1 +.L0: + mov w0, wzr +.L1: + cmp x0, #0 + b.lt .L2 +.L2: + nop + .cfi_restore_state + mov x8, xzr + b.ls .L0 + ret +.cfi_endproc + .size main, .-main + +## Force relocation mode. + .reloc 0, R_AARCH64_NONE