Support unwinding from inline assembly · llvm/llvm-project@8ec9fd4 (original) (raw)

`@@ -2138,13 +2138,15 @@ static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str,

`

2138

2138

`}

`

2139

2139

``

2140

2140

`static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,

`

2141

``

`-

bool ReadOnly, bool ReadNone, bool NoMerge,

`

2142

``

`-

const AsmStmt &S,

`

``

2141

`+

bool HasUnwindClobber, bool ReadOnly,

`

``

2142

`+

bool ReadNone, bool NoMerge, const AsmStmt &S,

`

2143

2143

`const std::vector<llvm::Type *> &ResultRegTypes,

`

2144

2144

` CodeGenFunction &CGF,

`

2145

2145

` std::vector<llvm::Value *> &RegResults) {

`

2146

``

`-

Result.addAttribute(llvm::AttributeList::FunctionIndex,

`

2147

``

`-

llvm::Attribute::NoUnwind);

`

``

2146

`+

if (!HasUnwindClobber)

`

``

2147

`+

Result.addAttribute(llvm::AttributeList::FunctionIndex,

`

``

2148

`+

llvm::Attribute::NoUnwind);

`

``

2149

+

2148

2150

`if (NoMerge)

`

2149

2151

` Result.addAttribute(llvm::AttributeList::FunctionIndex,

`

2150

2152

` llvm::Attribute::NoMerge);

`

`@@ -2491,13 +2493,18 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {

`

2491

2493

` }

`

2492

2494

` Constraints += InOutConstraints;

`

2493

2495

``

``

2496

`+

bool HasUnwindClobber = false;

`

``

2497

+

2494

2498

`// Clobbers

`

2495

2499

`for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {

`

2496

2500

` StringRef Clobber = S.getClobber(i);

`

2497

2501

``

2498

2502

`if (Clobber == "memory")

`

2499

2503

` ReadOnly = ReadNone = false;

`

2500

``

`-

else if (Clobber != "cc") {

`

``

2504

`+

else if (Clobber == "unwind") {

`

``

2505

`+

HasUnwindClobber = true;

`

``

2506

`+

continue;

`

``

2507

`+

} else if (Clobber != "cc") {

`

2501

2508

` Clobber = getTarget().getNormalizedGCCRegisterName(Clobber);

`

2502

2509

`if (CGM.getCodeGenOpts().StackClashProtector &&

`

2503

2510

`getTarget().isSPRegName(Clobber)) {

`

`@@ -2531,6 +2538,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {

`

2531

2538

` Constraints += '}';

`

2532

2539

` }

`

2533

2540

``

``

2541

`+

assert(!(HasUnwindClobber && IsGCCAsmGoto) &&

`

``

2542

`+

"unwind clobber can't be used with asm goto");

`

``

2543

+

2534

2544

`// Add machine specific clobbers

`

2535

2545

` std::string MachineClobbers = getTarget().getClobbers();

`

2536

2546

`if (!MachineClobbers.empty()) {

`

`@@ -2553,23 +2563,28 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {

`

2553

2563

`bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0;

`

2554

2564

` llvm::InlineAsm::AsmDialect AsmDialect = isa(&S) ?

`

2555

2565

` llvm::InlineAsm::AD_Intel : llvm::InlineAsm::AD_ATT;

`

2556

``

`-

llvm::InlineAsm *IA =

`

2557

``

`-

llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect,

`

2558

``

`-

/* IsAlignStack */ false, AsmDialect);

`

``

2566

`+

llvm::InlineAsm *IA = llvm::InlineAsm::get(

`

``

2567

`+

FTy, AsmString, Constraints, HasSideEffect,

`

``

2568

`+

/* IsAlignStack */ false, AsmDialect, HasUnwindClobber);

`

2559

2569

` std::vectorllvm::Value* RegResults;

`

2560

2570

`if (IsGCCAsmGoto) {

`

2561

2571

` llvm::CallBrInst *Result =

`

2562

2572

` Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);

`

2563

2573

`EmitBlock(Fallthrough);

`

2564

``

`-

UpdateAsmCallInst(castllvm::CallBase(*Result), HasSideEffect, ReadOnly,

`

2565

``

`-

ReadNone, InNoMergeAttributedStmt, S, ResultRegTypes,

`

2566

``

`-

*this, RegResults);

`

``

2574

`+

UpdateAsmCallInst(castllvm::CallBase(*Result), HasSideEffect, false,

`

``

2575

`+

ReadOnly, ReadNone, InNoMergeAttributedStmt, S,

`

``

2576

`+

ResultRegTypes, *this, RegResults);

`

``

2577

`+

} else if (HasUnwindClobber) {

`

``

2578

`+

llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, "");

`

``

2579

`+

UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone,

`

``

2580

`+

InNoMergeAttributedStmt, S, ResultRegTypes, *this,

`

``

2581

`+

RegResults);

`

2567

2582

` } else {

`

2568

2583

` llvm::CallInst *Result =

`

2569

2584

` Builder.CreateCall(IA, Args, getBundlesForFunclet(IA));

`

2570

``

`-

UpdateAsmCallInst(castllvm::CallBase(*Result), HasSideEffect, ReadOnly,

`

2571

``

`-

ReadNone, InNoMergeAttributedStmt, S, ResultRegTypes,

`

2572

``

`-

*this, RegResults);

`

``

2585

`+

UpdateAsmCallInst(castllvm::CallBase(*Result), HasSideEffect, false,

`

``

2586

`+

ReadOnly, ReadNone, InNoMergeAttributedStmt, S,

`

``

2587

`+

ResultRegTypes, *this, RegResults);

`

2573

2588

` }

`

2574

2589

``

2575

2590

`assert(RegResults.size() == ResultRegTypes.size());

`