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());
`