I somewhat recently stumbled upon a somewhat annoying pattern while traversing a RISCV-32 program. It looked just a little like this in the Listing:

	     **************************************************************
	     *                          FUNCTION                          *
	     **************************************************************
	     undefined example_fn()
undefined         <UNASSIGNED>   <RETURN>
	     example                                    
ef b2 86 fb     jal        t0,prologue_stub_t0                              void prologue_stub_t0(void)
			    <...SNIP...>
6f b0 86 f9     j          epilogue_stub_ret                                void epilogue_stub_ret(void)

And like this in the Decompiler:

void example_fn(undefined1 *param_1,int param_2)

{
  int iVar1;
  undefined4 uVar1;
  undefined4 uVar2;

  iVar1 = prologue_stub_t0();
  
  uVar1 = 0x12;
  if (iVar1 == extraout_a1){
    uVar1 = 0x17;
  }
  
  uVar2 = epilogue_stub_ret(uVar1);
  return uVar2;
}

So where were these jalr, and j instructions going? To outlined callee-saved register preservation and restoration: