[PATCH] Save the link register for uwtable.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Sat Feb 22 06:55:47 PST 2014


I am not currently familiar with ARM, but if I understand it correctly
the situation is

* We cannot tail call for some reason, or doing a jump would be safe.
* The arm call instruction doesn't automatically save the link
register, but the ABI specifies where to find it, so we don't need to
write its location on a table (like .eh_table).

And then what this patch does is force the link register to be saved
so that we can unwind past this call. If the above assumptions are
correct, the patch is probably fine, but please wait for a review by
some working with the  ARM target.


On 22 February 2014 07:12, Logan Chien <tzuhsiang.chien at gmail.com> wrote:
> Hi qcolombet,
>
> The function with uwtable attribute might be visited by the
> stack unwinder, thus we should not optimize out the instructions
> to save the link register if the caller function has uwtable
> attribute.
>
> http://llvm-reviews.chandlerc.com/D2863
>
> Files:
>   lib/CodeGen/VirtRegMap.cpp
>   test/CodeGen/ARM/noreturn.ll
>
> Index: lib/CodeGen/VirtRegMap.cpp
> ===================================================================
> --- lib/CodeGen/VirtRegMap.cpp
> +++ lib/CodeGen/VirtRegMap.cpp
> @@ -278,6 +278,11 @@
>    PhysRegs.clear();
>    PhysRegs.setUniverse(TRI->getNumRegs());
>
> +  // The function with uwtable should guarantee that the stack unwinder
> +  // can unwind the stack to the previous frame.  Thus, we can't apply the
> +  // noreturn optimization if the caller function has uwtable attribute.
> +  bool HasUWTable = MF->getFunction()->hasFnAttribute(Attribute::UWTable);
> +
>    for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
>         MBBI != MBBE; ++MBBI) {
>      DEBUG(MBBI->print(dbgs(), Indexes));
> @@ -287,9 +292,12 @@
>        MachineInstr *MI = MII;
>        ++MII;
>
> -      // Check if this instruction is a call to a noreturn function.
> -      // If so, all the definitions set by this instruction can be ignored.
> -      if (IsExitBB && MI->isCall())
> +      // Check if this instruction is a call to a noreturn function.  If this
> +      // is a call to noreturn function and we don't need the stack unwinding
> +      // functionality (i.e. this function does not have uwtable attribute and
> +      // the callee function has the nounwind attribute), then we can ignore
> +      // the definitions set by this instruction.
> +      if (!HasUWTable && IsExitBB && MI->isCall())
>          for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
>                 MOE = MI->operands_end(); MOI != MOE; ++MOI) {
>            MachineOperand &MO = *MOI;
> Index: test/CodeGen/ARM/noreturn.ll
> ===================================================================
> --- test/CodeGen/ARM/noreturn.ll
> +++ test/CodeGen/ARM/noreturn.ll
> @@ -43,6 +43,23 @@
>    unreachable
>  }
>
> +; Test case for uwtable
> +define i32 @test4() uwtable {
> +; CHECK-LABEL: @test4
> +; CHECK: push
> +entry:
> +  tail call void @overflow() #0
> +  unreachable
> +}
> +
> +define i32 @test5() uwtable {
> +; CHECK-LABEL: @test5
> +; CHECK: push
> +entry:
> +  tail call void @overflow_with_unwind() #1
> +  unreachable
> +}
> +
>  ; Function Attrs: noreturn
>  declare void @overflow_with_unwind() #1



More information about the llvm-commits mailing list