Throwing function being marked nounwind under optimzation?


The following relatively simple function is behaving oddly under SJLJ exception handling. Specifically, it's being diagnosed by the optimizer as being a nounwind function, which is obviously incorrect.

From what I can tell so far, something is going wrong analyzing the call to __cxa_end_catch()
   invoke arm_apcscc void @__cxa_end_catch()
           to label %Unwind unwind label %lpad121
Something thinks that this invoke will always take the unwind path, which isn't the case, and marks the Unwind block as unreachable. As a consequence of that, the call to _Unwind_SjLj_Resume() is optimized away, and thus the function is considered to not throw in PruneEH.cpp. Very strange stuff.

Thoughts on how to proceed in figuring out the root cause of what's going wrong?

bool ShouldThrow;

int throws()
   if (ShouldThrow) throw 7; return 123;
} catch (...) {
   printf("'throws' threw an exception: rethrowing!\n");

It would help if you post the -O0 and -O1bitcode files.

Does it reproduce with opt -O1? If so, use -debug-pass= to figure out when things started going wrong.

Does it make sense to compare the bitcode against code generated for x86 target?


Attached .bc files from -O0, -O1 and an X86 -O1. Comparing against the x86 code is somewhat useful, as the core control flow for EH should be the same. The SJLJ bits add a bit of wrapper around it and some annotations (call_site stuff).

It does reproduce when running "opt -O1." That's a good suggestion. Thanks. I'll see where that leads.

Comparing to the x86 output also makes good sense. Doing that is what led me noticing that the Unwind block was getting optimized away.

function_try_block.O0.bc (2.34 KB)

function_try_block.O1.bc (1.63 KB)

function_try_block.x86.bc (1.58 KB)