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
This commit is contained in:
@@ -2830,7 +2830,7 @@ Error BitcodeReader::parseConstants() {
|
||||
}
|
||||
// This version adds support for the asm dialect keywords (e.g.,
|
||||
// inteldialect).
|
||||
case bitc::CST_CODE_INLINEASM: {
|
||||
case bitc::CST_CODE_INLINEASM_OLD2: {
|
||||
if (Record.size() < 2)
|
||||
return error("Invalid record");
|
||||
std::string AsmStr, ConstrStr;
|
||||
@@ -2855,6 +2855,33 @@ Error BitcodeReader::parseConstants() {
|
||||
InlineAsm::AsmDialect(AsmDialect));
|
||||
break;
|
||||
}
|
||||
// This version adds support for the unwind keyword.
|
||||
case bitc::CST_CODE_INLINEASM: {
|
||||
if (Record.size() < 2)
|
||||
return error("Invalid record");
|
||||
std::string AsmStr, ConstrStr;
|
||||
bool HasSideEffects = Record[0] & 1;
|
||||
bool IsAlignStack = (Record[0] >> 1) & 1;
|
||||
unsigned AsmDialect = (Record[0] >> 2) & 1;
|
||||
bool CanThrow = (Record[0] >> 3) & 1;
|
||||
unsigned AsmStrSize = Record[1];
|
||||
if (2 + AsmStrSize >= Record.size())
|
||||
return error("Invalid record");
|
||||
unsigned ConstStrSize = Record[2 + AsmStrSize];
|
||||
if (3 + AsmStrSize + ConstStrSize > Record.size())
|
||||
return error("Invalid record");
|
||||
|
||||
for (unsigned i = 0; i != AsmStrSize; ++i)
|
||||
AsmStr += (char)Record[2 + i];
|
||||
for (unsigned i = 0; i != ConstStrSize; ++i)
|
||||
ConstrStr += (char)Record[3 + AsmStrSize + i];
|
||||
UpgradeInlineAsmString(&AsmStr);
|
||||
V = InlineAsm::get(
|
||||
cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr,
|
||||
ConstrStr, HasSideEffects, IsAlignStack,
|
||||
InlineAsm::AsmDialect(AsmDialect), CanThrow);
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_BLOCKADDRESS:{
|
||||
if (Record.size() < 3)
|
||||
return error("Invalid record");
|
||||
|
||||
Reference in New Issue
Block a user