Support unwinding from inline assembly
I've taken the following steps to add unwinding support from inline assembly:
1) Add a new `unwind` "attribute" (like `sideeffect`) to the asm syntax:
```
invoke void asm sideeffect unwind "call thrower", "~{dirflag},~{fpsr},~{flags}"()
to label %exit unwind label %uexit
```
2.) Add Bitcode writing/reading support + LLVM-IR parsing.
3.) Emit EHLabels around inline assembly lowering (SelectionDAGBuilder + GlobalISel) when `InlineAsm::canThrow` is enabled.
4.) Tweak InstCombineCalls/InlineFunction pass to not mark inline assembly "calls" as nounwind.
5.) Add clang support by introducing a new clobber: "unwind", which lower to the `canThrow` being enabled.
6.) Don't allow unwinding callbr.
Reviewed By: Amanieu
Differential Revision: https://reviews.llvm.org/D95745
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 156f4c0..084ad5d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -759,7 +759,8 @@
void visitStoreToSwiftError(const StoreInst &I);
void visitFreeze(const FreezeInst &I);
- void visitInlineAsm(const CallBase &Call);
+ void visitInlineAsm(const CallBase &Call,
+ const BasicBlock *EHPadBB = nullptr);
void visitIntrinsicCall(const CallInst &I, unsigned Intrinsic);
void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic);
void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI);
@@ -816,6 +817,11 @@
/// Lowers CallInst to an external symbol.
void lowerCallToExternalSymbol(const CallInst &I, const char *FunctionName);
+
+ SDValue lowerStartEH(SDValue Chain, const BasicBlock *EHPadBB,
+ MCSymbol *&BeginLabel);
+ SDValue lowerEndEH(SDValue Chain, const InvokeInst *II,
+ const BasicBlock *EHPadBB, MCSymbol *BeginLabel);
};
/// This struct represents the registers (physical or virtual)