forked from xt-sys/xtchain
		
	Update hardware exceptions patch
This commit is contained in:
		| @@ -1,5 +1,5 @@ | |||||||
| diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h | diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h | ||||||
| index d3fad58fcf5..dccbbe2fade 100644 | index d3fad58fcf5..77153f85a93 100644 | ||||||
| --- a/clang/include/clang/AST/Stmt.h | --- a/clang/include/clang/AST/Stmt.h | ||||||
| +++ b/clang/include/clang/AST/Stmt.h | +++ b/clang/include/clang/AST/Stmt.h | ||||||
| @@ -1764,6 +1764,7 @@ public: | @@ -1764,6 +1764,7 @@ public: | ||||||
| @@ -16,7 +16,7 @@ index d3fad58fcf5..dccbbe2fade 100644 | |||||||
|    } |    } | ||||||
| + | + | ||||||
| +  bool isSideEntry() const { return SideEntry; } | +  bool isSideEntry() const { return SideEntry; } | ||||||
| +  void setSideEntry() { SideEntry = true; } | +  void setSideEntry(bool SE) { SideEntry = SE; } | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  /// Represents an attribute applied to a statement. |  /// Represents an attribute applied to a statement. | ||||||
| @@ -53,18 +53,64 @@ index 966cb907b7e..dc7b38c254f 100644 | |||||||
|  def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>, |  def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>, | ||||||
|    Flags<[DriverOption]>; |    Flags<[DriverOption]>; | ||||||
|  def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>, |  def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>, | ||||||
|  | diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp | ||||||
|  | index 4bd00ece86a..7cc6089b711 100644 | ||||||
|  | --- a/clang/lib/AST/JSONNodeDumper.cpp | ||||||
|  | +++ b/clang/lib/AST/JSONNodeDumper.cpp | ||||||
|  | @@ -1444,6 +1444,7 @@ void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) { | ||||||
|  |  void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) { | ||||||
|  |    JOS.attribute("name", LS->getName()); | ||||||
|  |    JOS.attribute("declId", createPointerRepresentation(LS->getDecl())); | ||||||
|  | +  attributeOnlyIfTrue("sideEntry", LS->isSideEntry()); | ||||||
|  |  } | ||||||
|  |  void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) { | ||||||
|  |    JOS.attribute("targetLabelDeclId", | ||||||
|  | diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp | ||||||
|  | index 5b0a0ac392c..0d5e9418fb7 100644 | ||||||
|  | --- a/clang/lib/AST/TextNodeDumper.cpp | ||||||
|  | +++ b/clang/lib/AST/TextNodeDumper.cpp | ||||||
|  | @@ -916,6 +916,8 @@ void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) { | ||||||
|  |   | ||||||
|  |  void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) { | ||||||
|  |    OS << " '" << Node->getName() << "'"; | ||||||
|  | +  if (Node->isSideEntry()) | ||||||
|  | +    OS << " side_entry"; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) { | ||||||
| diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp | diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp | ||||||
| index ad543ef86c1..7c1902f080f 100644 | index ad543ef86c1..3b69bb20b06 100644 | ||||||
| --- a/clang/lib/CodeGen/CGCleanup.cpp | --- a/clang/lib/CodeGen/CGCleanup.cpp | ||||||
| +++ b/clang/lib/CodeGen/CGCleanup.cpp | +++ b/clang/lib/CodeGen/CGCleanup.cpp | ||||||
| @@ -763,10 +763,22 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { | @@ -194,6 +194,11 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) { | ||||||
|  |    if (IsLifetimeMarker) | ||||||
|  |      Scope->setLifetimeMarker(); | ||||||
|  |   | ||||||
|  | +  // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup | ||||||
|  | +  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&  | ||||||
|  | +    CGF->getTarget().getCXXABI().isMicrosoft()) | ||||||
|  | +    CGF->EmitSehCppScopeBegin(); | ||||||
|  | + | ||||||
|  |    return Scope->getCleanupBuffer(); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -759,14 +764,31 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { | ||||||
|  |    if (Scope.isEHCleanup()) | ||||||
|  |      cleanupFlags.setIsEHCleanupKind(); | ||||||
|  |   | ||||||
|  | +  // Under -EHa, invoke seh.scope.end() to mark scope end before dtor | ||||||
|  | +  bool IsEHa = getLangOpts().EHAsynch && !Scope.isLifetimeMarker(); | ||||||
|  | +  const EHPersonality& Personality = EHPersonality::get(*this); | ||||||
|  |    if (!RequiresNormalCleanup) { | ||||||
|  | +    // Mark CPP scope end for passed-by-value Arg temp | ||||||
|  | +    //   per Windows ABI which is "normally" Cleanup in callee | ||||||
|  | +    if (IsEHa && getInvokeDest()) { | ||||||
|  | +      if (Personality.isMSVCXXPersonality()) | ||||||
|  | +        EmitSehCppScopeEnd(); | ||||||
|  | +    } | ||||||
|      destroyOptimisticNormalEntry(*this, Scope); |      destroyOptimisticNormalEntry(*this, Scope); | ||||||
|      EHStack.popCleanup(); |      EHStack.popCleanup(); | ||||||
|    } else { |    } else { | ||||||
| +    // Under -EHa, invoke eha_scope_end() to mark scope end before dtor |  | ||||||
| +    bool IsEHa = getLangOpts().EHAsynch && !Scope.isLifetimeMarker(); |  | ||||||
| +    const EHPersonality &Personality = EHPersonality::get(*this); |  | ||||||
| + |  | ||||||
|      // If we have a fallthrough and no other need for the cleanup, |      // If we have a fallthrough and no other need for the cleanup, | ||||||
|      // emit it directly. |      // emit it directly. | ||||||
| -    if (HasFallthrough && !HasPrebranchedFallthrough && | -    if (HasFallthrough && !HasPrebranchedFallthrough && | ||||||
| @@ -72,39 +118,63 @@ index ad543ef86c1..7c1902f080f 100644 | |||||||
| +    if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups && | +    if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups && | ||||||
| +        !HasExistingBranches) { | +        !HasExistingBranches) { | ||||||
| + | + | ||||||
| +      // mark EHa scope end for fall-through flow | +      // mark SEH scope end for fall-through flow | ||||||
| +      if (IsEHa && getInvokeDest()) | +      if (IsEHa && getInvokeDest()) { | ||||||
| +        if (Personality.isMSVCXXPersonality()) | +        if (Personality.isMSVCXXPersonality()) | ||||||
| +          EmitSehCppScopeEnd(); | +          EmitSehCppScopeEnd(); | ||||||
| +        else { | +        else | ||||||
| +          EmitSehTryScopeEnd(); | +          EmitSehTryScopeEnd(); | ||||||
| +        } | +      } | ||||||
|   |   | ||||||
|        destroyOptimisticNormalEntry(*this, Scope); |        destroyOptimisticNormalEntry(*this, Scope); | ||||||
|        EHStack.popCleanup(); |        EHStack.popCleanup(); | ||||||
| @@ -801,6 +813,14 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { | @@ -801,6 +823,14 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { | ||||||
|        // should already be branched to it. |        // should already be branched to it. | ||||||
|        EmitBlock(NormalEntry); |        EmitBlock(NormalEntry); | ||||||
|   |   | ||||||
| +      // intercept normal cleanup to mark EHa scope end | +      // intercept normal cleanup to mark SEH scope end | ||||||
| +      if (IsEHa) | +      if (IsEHa) { | ||||||
| +        if (Personality.isMSVCXXPersonality()) | +        if (Personality.isMSVCXXPersonality()) | ||||||
| +          EmitSehCppScopeEnd(); | +          EmitSehCppScopeEnd(); | ||||||
| +        else { | +        else | ||||||
| +          EmitSehTryScopeEnd(); | +          EmitSehTryScopeEnd(); | ||||||
| +        } | +      } | ||||||
| + | + | ||||||
|        // III.  Figure out where we're going and build the cleanup |        // III.  Figure out where we're going and build the cleanup | ||||||
|        // epilogue. |        // epilogue. | ||||||
|   |   | ||||||
| @@ -1276,3 +1296,61 @@ void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary, | @@ -1248,11 +1278,18 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, | ||||||
|  |    // to the current RunCleanupsScope. | ||||||
|  |    if (C == EHStack.stable_begin() && | ||||||
|  |        CurrentCleanupScopeDepth.strictlyEncloses(C)) { | ||||||
|  | -    // If it's a normal cleanup, we need to pretend that the | ||||||
|  | -    // fallthrough is unreachable. | ||||||
|  | -    CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); | ||||||
|  | -    PopCleanupBlock(); | ||||||
|  | -    Builder.restoreIP(SavedIP); | ||||||
|  | +    // Per comment below, checking EHAsynch is not really necessary | ||||||
|  | +    // it's there to assure zero-impact w/o EHAsynch option | ||||||
|  | +    if (!Scope.isNormalCleanup() && getLangOpts().EHAsynch) | ||||||
|  | +      PopCleanupBlock(); | ||||||
|  | +    else | ||||||
|  | +    { | ||||||
|  | +      // If it's a normal cleanup, we need to pretend that the | ||||||
|  | +      // fallthrough is unreachable. | ||||||
|  | +      CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); | ||||||
|  | +      PopCleanupBlock(); | ||||||
|  | +      Builder.restoreIP(SavedIP); | ||||||
|  | +    } | ||||||
|  |      return; | ||||||
|  |    } | ||||||
|  |   | ||||||
|  | @@ -1276,3 +1313,60 @@ void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary, | ||||||
|    pushDestroy(NormalAndEHCleanup, Ptr, TempType, destroyCXXObject, |    pushDestroy(NormalAndEHCleanup, Ptr, TempType, destroyCXXObject, | ||||||
|                /*useEHCleanup*/ true); |                /*useEHCleanup*/ true); | ||||||
|  } |  } | ||||||
| + | + | ||||||
| +// Need to set "funclet" in OperandBundle properly for noThrow | +// Need to set "funclet" in OperandBundle properly for noThrow | ||||||
| +//       intrinsic (see CGCall.cpp) | +//       intrinsic (see CGCall.cpp) | ||||||
| +static void EmitSehEHaScope(CodeGenFunction &CGF, | +static void EmitSehScope(CodeGenFunction &CGF, | ||||||
| +                            llvm::FunctionCallee &SehCppScope) { | +                            llvm::FunctionCallee &SehCppScope) { | ||||||
| +  llvm::BasicBlock *InvokeDest = CGF.getInvokeDest(); | +  llvm::BasicBlock *InvokeDest = CGF.getInvokeDest(); | ||||||
| +  llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock(); | +  llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock(); | ||||||
| @@ -118,69 +188,47 @@ index ad543ef86c1..7c1902f080f 100644 | |||||||
| +  CGF.EmitBlock(Cont); | +  CGF.EmitBlock(Cont); | ||||||
| +} | +} | ||||||
| + | + | ||||||
| +// Invoke a llvm.eha.scope.begin at the beginning of a CPP scope for -EHa | +// Invoke a llvm.seh.scope.begin at the beginning of a CPP scope for -EHa | ||||||
| +void CodeGenFunction::EmitSehCppScopeBegin() { | +void CodeGenFunction::EmitSehCppScopeBegin() { | ||||||
| +  assert(getLangOpts().EHAsynch); | +  assert(getLangOpts().EHAsynch); | ||||||
| +  llvm::FunctionType *FTy = | +  llvm::FunctionType *FTy = | ||||||
| +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | ||||||
| +  llvm::FunctionCallee SehCppScope = | +  llvm::FunctionCallee SehCppScope = | ||||||
| +      CGM.CreateRuntimeFunction(FTy, "llvm.eha.scope.begin"); | +      CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.begin"); | ||||||
| +  EmitSehEHaScope(*this, SehCppScope); | +  EmitSehScope(*this, SehCppScope); | ||||||
| +} | +} | ||||||
| + | + | ||||||
| +// Invoke a llvm.eha.scope.end at the end of a CPP scope for -EHa | +// Invoke a llvm.seh.scope.end at the end of a CPP scope for -EHa | ||||||
| +//   llvm.eha.scope.end is emitted before popCleanup, so it's "invoked" | +//   llvm.seh.scope.end is emitted before popCleanup, so it's "invoked" | ||||||
| +void CodeGenFunction::EmitSehCppScopeEnd() { | +void CodeGenFunction::EmitSehCppScopeEnd() { | ||||||
| +  assert(getLangOpts().EHAsynch); | +  assert(getLangOpts().EHAsynch); | ||||||
| +  llvm::FunctionType *FTy = | +  llvm::FunctionType *FTy = | ||||||
| +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | ||||||
| +  llvm::FunctionCallee SehCppScope = | +  llvm::FunctionCallee SehCppScope = | ||||||
| +      CGM.CreateRuntimeFunction(FTy, "llvm.eha.scope.end"); | +      CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.end"); | ||||||
| +  EmitSehEHaScope(*this, SehCppScope); | +  EmitSehScope(*this, SehCppScope); | ||||||
| +} | +} | ||||||
| + | + | ||||||
| +// Invoke a llvm.eha.scope.begin at the beginning of a CPP scope for -EHa | +// Invoke a llvm.seh.try.begin at the beginning of a SEH scope for -EHa | ||||||
| +void CodeGenFunction::EmitSehTryScopeBegin() { | +void CodeGenFunction::EmitSehTryScopeBegin() { | ||||||
| +  assert(getLangOpts().EHAsynch); | +  assert(getLangOpts().EHAsynch); | ||||||
| +  llvm::FunctionType *FTy = | +  llvm::FunctionType* FTy = | ||||||
| +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | +    llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | ||||||
| +  llvm::FunctionCallee SehCppScope = | +  llvm::FunctionCallee SehCppScope = | ||||||
| +      CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin"); | +    CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin"); | ||||||
| +  EmitSehEHaScope(*this, SehCppScope); | +  EmitSehScope(*this, SehCppScope); | ||||||
| +} | +} | ||||||
| + | + | ||||||
| +// Invoke a llvm.eha.scope.end at the end of a CPP scope for -EHa | +// Invoke a llvm.seh.try.end at the end of a SEH scope for -EHa | ||||||
| +//   llvm.eha.scope.end is emitted before popCleanup, so it's "invoked" |  | ||||||
| +void CodeGenFunction::EmitSehTryScopeEnd() { | +void CodeGenFunction::EmitSehTryScopeEnd() { | ||||||
| +  assert(getLangOpts().EHAsynch); | +  assert(getLangOpts().EHAsynch); | ||||||
| +  llvm::FunctionType *FTy = | +  llvm::FunctionType* FTy = | ||||||
| +      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | +    llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); | ||||||
| +  llvm::FunctionCallee SehCppScope = | +  llvm::FunctionCallee SehCppScope = | ||||||
| +      CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end"); | +    CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end"); | ||||||
| +  EmitSehEHaScope(*this, SehCppScope); | +  EmitSehScope(*this, SehCppScope); | ||||||
| +} | +} | ||||||
| diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp | \ No newline at end of file | ||||||
| index 1729c7ed3c3..c9107b1296f 100644 |  | ||||||
| --- a/clang/lib/CodeGen/CGDecl.cpp |  | ||||||
| +++ b/clang/lib/CodeGen/CGDecl.cpp |  | ||||||
| @@ -2006,9 +2006,16 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { |  | ||||||
|    const VarDecl &D = *emission.Variable; |  | ||||||
|   |  | ||||||
|    // Check the type for a cleanup. |  | ||||||
| -  if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext())) |  | ||||||
| +  if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext())) { |  | ||||||
|      emitAutoVarTypeCleanup(emission, dtorKind); |  | ||||||
|   |  | ||||||
| +    // Under -EHa, Invoke llvm.eha.scope.begin() right after |  | ||||||
| +    //   Ctor is emitted and EHStack.pushCleanup |  | ||||||
| +    bool IsEHa = getLangOpts().EHAsynch; |  | ||||||
| +    if (IsEHa && dtorKind == QualType::DK_cxx_destructor) |  | ||||||
| +      EmitSehCppScopeBegin(); |  | ||||||
| +  } |  | ||||||
| + |  | ||||||
|    // In GC mode, honor objc_precise_lifetime. |  | ||||||
|    if (getLangOpts().getGC() != LangOptions::NonGC && |  | ||||||
|        D.hasAttr<ObjCPreciseLifetimeAttr>()) { |  | ||||||
| diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp | diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp | ||||||
| index bdf70252b5a..a4e4d7d8120 100644 | index bdf70252b5a..a4e4d7d8120 100644 | ||||||
| --- a/clang/lib/CodeGen/CGException.cpp | --- a/clang/lib/CodeGen/CGException.cpp | ||||||
| @@ -353,6 +401,18 @@ index 672909849bb..32dca08b8cf 100644 | |||||||
|    EmitStmt(S.getSubStmt()); |    EmitStmt(S.getSubStmt()); | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  | diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp | ||||||
|  | index 8ce488f35dd..4cc8304c455 100644 | ||||||
|  | --- a/clang/lib/CodeGen/CodeGenFunction.cpp | ||||||
|  | +++ b/clang/lib/CodeGen/CodeGenFunction.cpp | ||||||
|  | @@ -71,6 +71,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) | ||||||
|  |            shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) { | ||||||
|  |    if (!suppressNewContext) | ||||||
|  |      CGM.getCXXABI().getMangleContext().startNewFunction(); | ||||||
|  | +  EHStack.setCGF(this); | ||||||
|  |   | ||||||
|  |    SetFastMathFlags(CurFPFeatures); | ||||||
|  |    SetFPModel(); | ||||||
| diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h | diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h | ||||||
| index d794f4f0fa8..1b5892c7459 100644 | index d794f4f0fa8..1b5892c7459 100644 | ||||||
| --- a/clang/lib/CodeGen/CodeGenFunction.h | --- a/clang/lib/CodeGen/CodeGenFunction.h | ||||||
| @@ -392,6 +452,38 @@ index 4ae8ce7e5cc..5512c8fe88a 100644 | |||||||
|    // Emit OpenCL specific module metadata: OpenCL/SPIR version. |    // Emit OpenCL specific module metadata: OpenCL/SPIR version. | ||||||
|    if (LangOpts.OpenCL) { |    if (LangOpts.OpenCL) { | ||||||
|      EmitOpenCLMetadata(); |      EmitOpenCLMetadata(); | ||||||
|  | diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h | ||||||
|  | index 3a640d6117d..60fe9b3c9dd 100644 | ||||||
|  | --- a/clang/lib/CodeGen/EHScopeStack.h | ||||||
|  | +++ b/clang/lib/CodeGen/EHScopeStack.h | ||||||
|  | @@ -236,6 +236,9 @@ private: | ||||||
|  |    /// The innermost EH scope on the stack. | ||||||
|  |    stable_iterator InnermostEHScope; | ||||||
|  |   | ||||||
|  | +  /// The CGF this Stack belong to | ||||||
|  | +  CodeGenFunction* CGF; | ||||||
|  | + | ||||||
|  |    /// The current set of branch fixups.  A branch fixup is a jump to | ||||||
|  |    /// an as-yet unemitted label, i.e. a label for which we don't yet | ||||||
|  |    /// know the EH stack depth.  Whenever we pop a cleanup, we have | ||||||
|  | @@ -263,7 +266,7 @@ private: | ||||||
|  |  public: | ||||||
|  |    EHScopeStack() : StartOfBuffer(nullptr), EndOfBuffer(nullptr), | ||||||
|  |                     StartOfData(nullptr), InnermostNormalCleanup(stable_end()), | ||||||
|  | -                   InnermostEHScope(stable_end()) {} | ||||||
|  | +                   InnermostEHScope(stable_end()), CGF(nullptr) {} | ||||||
|  |    ~EHScopeStack() { delete[] StartOfBuffer; } | ||||||
|  |   | ||||||
|  |    /// Push a lazily-created cleanup on the stack. | ||||||
|  | @@ -311,6 +314,8 @@ public: | ||||||
|  |      std::memcpy(Buffer, Cleanup, Size); | ||||||
|  |    } | ||||||
|  |   | ||||||
|  | +  void setCGF(CodeGenFunction* inCGF) { CGF = inCGF; } | ||||||
|  | + | ||||||
|  |    /// Pops a cleanup scope off the stack.  This is private to CGCleanup.cpp. | ||||||
|  |    void popCleanup(); | ||||||
|  |   | ||||||
| diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp | diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp | ||||||
| index 45c6cb6b2e0..a080c93356a 100644 | index 45c6cb6b2e0..a080c93356a 100644 | ||||||
| --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp | --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp | ||||||
| @@ -460,7 +552,7 @@ index 73114c6d76c..b58af0b68e7 100644 | |||||||
|    // -ffixed-point |    // -ffixed-point | ||||||
|    Opts.FixedPoint = |    Opts.FixedPoint = | ||||||
| diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp | diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp | ||||||
| index b34243edea3..cbc309a3d42 100644 | index b34243edea3..304f059a032 100644 | ||||||
| --- a/clang/lib/Sema/JumpDiagnostics.cpp | --- a/clang/lib/Sema/JumpDiagnostics.cpp | ||||||
| +++ b/clang/lib/Sema/JumpDiagnostics.cpp | +++ b/clang/lib/Sema/JumpDiagnostics.cpp | ||||||
| @@ -930,6 +930,9 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc, | @@ -930,6 +930,9 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc, | ||||||
| @@ -469,13 +561,43 @@ index b34243edea3..cbc309a3d42 100644 | |||||||
|      NoteJumpIntoScopes(ToScopesWarning); |      NoteJumpIntoScopes(ToScopesWarning); | ||||||
| +    assert(isa<LabelStmt>(To)); | +    assert(isa<LabelStmt>(To)); | ||||||
| +    LabelStmt *Label = cast<LabelStmt>(To); | +    LabelStmt *Label = cast<LabelStmt>(To); | ||||||
| +    Label->setSideEntry(); | +    Label->setSideEntry(true); | ||||||
|    } |    } | ||||||
|   |   | ||||||
|    // Handle errors. |    // Handle errors. | ||||||
|  | diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp | ||||||
|  | index a40c5499a6d..bfed22a1252 100644 | ||||||
|  | --- a/clang/lib/Serialization/ASTReaderStmt.cpp | ||||||
|  | +++ b/clang/lib/Serialization/ASTReaderStmt.cpp | ||||||
|  | @@ -185,11 +185,13 @@ void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) { | ||||||
|  |   | ||||||
|  |  void ASTStmtReader::VisitLabelStmt(LabelStmt *S) { | ||||||
|  |    VisitStmt(S); | ||||||
|  | +  bool IsSideEntry = Record.readInt(); | ||||||
|  |    auto *LD = readDeclAs<LabelDecl>(); | ||||||
|  |    LD->setStmt(S); | ||||||
|  |    S->setDecl(LD); | ||||||
|  |    S->setSubStmt(Record.readSubStmt()); | ||||||
|  |    S->setIdentLoc(readSourceLocation()); | ||||||
|  | +  S->setSideEntry(IsSideEntry); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { | ||||||
|  | diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp | ||||||
|  | index 0767b3a24bf..614fd45d193 100644 | ||||||
|  | --- a/clang/lib/Serialization/ASTWriterStmt.cpp | ||||||
|  | +++ b/clang/lib/Serialization/ASTWriterStmt.cpp | ||||||
|  | @@ -115,6 +115,7 @@ void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) { | ||||||
|  |   | ||||||
|  |  void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) { | ||||||
|  |    VisitStmt(S); | ||||||
|  | +  Record.push_back(S->isSideEntry()); | ||||||
|  |    Record.AddDeclRef(S->getDecl()); | ||||||
|  |    Record.AddStmt(S->getSubStmt()); | ||||||
|  |    Record.AddSourceLocation(S->getIdentLoc()); | ||||||
| diff --git a/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp b/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp | diff --git a/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp b/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp | ||||||
| new file mode 100644 | new file mode 100644 | ||||||
| index 00000000000..4f261ab59ee | index 00000000000..2928a610d3c | ||||||
| --- /dev/null | --- /dev/null | ||||||
| +++ b/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp | +++ b/clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp | ||||||
| @@ -0,0 +1,58 @@ | @@ -0,0 +1,58 @@ | ||||||
| @@ -483,8 +605,8 @@ index 00000000000..4f261ab59ee | |||||||
| + | + | ||||||
| +// CHECK: define dso_local void @"?crash@@YAXH@Z | +// CHECK: define dso_local void @"?crash@@YAXH@Z | ||||||
| +// CHECK: invoke void @llvm.seh.try.begin() | +// CHECK: invoke void @llvm.seh.try.begin() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.begin() | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.end() | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
| + | + | ||||||
| +// CHECK: %[[dst:[0-9-]+]] = catchswitch within none [label %catch] unwind to caller | +// CHECK: %[[dst:[0-9-]+]] = catchswitch within none [label %catch] unwind to caller | ||||||
| +// CHECK: %[[dst1:[0-9-]+]] = catchpad within %[[dst]] [i8* null, i32 0, i8* null] | +// CHECK: %[[dst1:[0-9-]+]] = catchpad within %[[dst]] [i8* null, i32 0, i8* null] | ||||||
| @@ -537,20 +659,156 @@ index 00000000000..4f261ab59ee | |||||||
| +  } | +  } | ||||||
| +  return 0; | +  return 0; | ||||||
| +} | +} | ||||||
|  | diff --git a/clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp b/clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp | ||||||
|  | new file mode 100644 | ||||||
|  | index 00000000000..d588d6e2292 | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp | ||||||
|  | @@ -0,0 +1,129 @@ | ||||||
|  | +// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s | ||||||
|  | + | ||||||
|  | +// CHECK: define dso_local i32 @"?bar@@YAHHVB1@@VB2@@@Z" | ||||||
|  | +// CHECK: %coerce.dive1 = getelementptr inbounds %class.B2 | ||||||
|  | +// CHECK: %coerce.dive2 = getelementptr inbounds %class.B1 | ||||||
|  | +// -----   scope begin of two passed-by-value temps   | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B1@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B2@@QEAA@XZ" | ||||||
|  | + | ||||||
|  | +// CHECK: define linkonce_odr dso_local void @"??1B2@@QEAA@XZ" | ||||||
|  | +// CHECK: %this.addr = alloca %class.B2* | ||||||
|  | +// -----  B1 scope begin without base ctor | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B1@@QEAA@XZ" | ||||||
|  | + | ||||||
|  | +// CHECK: define dso_local void @"?goo@@YA?AVB1@@H@Z" | ||||||
|  | +// CHECK: call %class.B2* @"??0B2@@QEAA@XZ"(%class.B2* %b2ingoo) | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// check: call void @llvm.memcpy | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B2@@QEAA@XZ"(%class.B2* %b2ingoo) | ||||||
|  | + | ||||||
|  | +// CHECK: define linkonce_odr dso_local %class.B2* @"??0B2@@QEAA@XZ" | ||||||
|  | +// CHECK: call %class.B1* @"??0B1@@QEAA@XZ"(%class.B1* | ||||||
|  | +// -----  scope begin of base ctor  | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// -----  B1 scope end without base dtor | ||||||
|  | + | ||||||
|  | +// **************************************************************************** | ||||||
|  | +// Abstract:     Test CPP Conditional-Expr & ABI Temps under SEH -EHa option | ||||||
|  | + | ||||||
|  | +void printf(...); | ||||||
|  | + | ||||||
|  | +int xxxx = 0; | ||||||
|  | +int* ptr;  | ||||||
|  | + | ||||||
|  | +int foo(int a) | ||||||
|  | +{ | ||||||
|  | +  return xxxx + a; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +class B1      { | ||||||
|  | +public: | ||||||
|  | +   int data = 90; | ||||||
|  | +   B1() { foo(data + 111); } | ||||||
|  | +    ~B1() { printf("in B1 Dtor \n"); } | ||||||
|  | +}; | ||||||
|  | +class B2 : public B1 { | ||||||
|  | +public: | ||||||
|  | +  B2() { foo(data + 222); } | ||||||
|  | +  ~B2() { printf("in B2 Dtor \n");; } | ||||||
|  | +}; | ||||||
|  | +class B3 : public B2 { | ||||||
|  | +public: | ||||||
|  | +  B3() { foo(data + 333); } | ||||||
|  | +  ~B3() { printf("in B3 Dtor \n");; } | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +int bar(int j, class B1 b1Bar, class B2 b2Bar) | ||||||
|  | +{ | ||||||
|  | +  int ww; | ||||||
|  | +  if ( j > 0) | ||||||
|  | +    ww = b1Bar.data; | ||||||
|  | +  else | ||||||
|  | +    ww = b2Bar.data; | ||||||
|  | +  return  ww + *ptr; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +class B1 goo(int w) | ||||||
|  | +{ | ||||||
|  | +  class B2 b2ingoo; | ||||||
|  | +  b2ingoo.data += w; | ||||||
|  | +  return b2ingoo; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +// CHECK: define dso_local i32 @main() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// ---   beginning of conditional temp test | ||||||
|  | +// CHECK: invoke %class.B2* @"??0B2@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke %class.B3* @"??0B3@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B3@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: call void @"??1B2@@QEAA@XZ" | ||||||
|  | +// -----  end of conditional temp test | ||||||
|  | + | ||||||
|  | +// -----  testing caller's passed-by-value temps | ||||||
|  | +//        setting scope in case exception occurs before the call | ||||||
|  | +// check: invoke %class.B2* @"??0B2@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke %class.B1* @"??0B1@@QEAA@XZ" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// -----   end of temps' scope right before callee | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | +// CHECK: invoke i32 @"?bar@@YAHHVB1@@VB2@@@Z" | ||||||
|  | + | ||||||
|  | +// -----  testing caller's return-by-value temp | ||||||
|  | +//        scope begins right after callee which is the ctor of return temp | ||||||
|  | +// CHECK: void @"?goo@@YA?AVB1@@H@Z" | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
|  | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
|  | + | ||||||
|  | +int main() { | ||||||
|  | +  class B3 b3inmain; | ||||||
|  | + | ||||||
|  | +  // Test conditional ctor and dtor | ||||||
|  | +  int m = (xxxx > 1) ? B2().data + foo(99) :  | ||||||
|  | +      B3().data + foo(88); | ||||||
|  | + | ||||||
|  | +  // Test: passed-in by value | ||||||
|  | +  // Per Windows ABI, ctored by caller, dtored by callee | ||||||
|  | +  int i = bar(foo(0), B1(), B2()); | ||||||
|  | + | ||||||
|  | +  // Test: returned by value | ||||||
|  | +  // Per Windows ABI, caller allocate a temp in stack, then ctored by callee,  | ||||||
|  | +  //          finally dtored in caller after consumed | ||||||
|  | +  class B1 b1fromgoo = goo(i); | ||||||
|  | + | ||||||
|  | +  return m + b1fromgoo.data + b3inmain.data; | ||||||
|  | +} | ||||||
|  | \ No newline at end of file | ||||||
| diff --git a/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp b/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp | diff --git a/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp b/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp | ||||||
| new file mode 100644 | new file mode 100644 | ||||||
| index 00000000000..d731bbb8ad2 | index 00000000000..8fdb1e889c4 | ||||||
| --- /dev/null | --- /dev/null | ||||||
| +++ b/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp | +++ b/clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp | ||||||
| @@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||||||
| +// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s | +// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s | ||||||
| + | + | ||||||
| +// CHECK: invoke void @llvm.eha.scope.begin() | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.begin() | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.begin() | +// CHECK: invoke void @llvm.seh.scope.begin() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.end() | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.end() | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
| +// CHECK: invoke void @llvm.eha.scope.end() | +// CHECK: invoke void @llvm.seh.scope.end() | ||||||
| + | + | ||||||
| +// CHECK: invoke void @llvm.seh.try.begin() | +// CHECK: invoke void @llvm.seh.try.begin() | ||||||
| +// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i | +// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i | ||||||
| @@ -652,10 +910,10 @@ index 00000000000..3efd7d6505f | |||||||
| +  return 0; | +  return 0; | ||||||
| +} | +} | ||||||
| diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst | diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst | ||||||
| index 9b58b9dfb17..1738ccd94ee 100644 | index 9b58b9dfb17..7ba418ab7d0 100644 | ||||||
| --- a/llvm/docs/LangRef.rst | --- a/llvm/docs/LangRef.rst | ||||||
| +++ b/llvm/docs/LangRef.rst | +++ b/llvm/docs/LangRef.rst | ||||||
| @@ -11642,6 +11642,59 @@ The '``llvm.localescape``' intrinsic blocks inlining, as inlining changes where | @@ -11642,6 +11642,66 @@ The '``llvm.localescape``' intrinsic blocks inlining, as inlining changes where | ||||||
|  the escaped allocas are allocated, which would break attempts to use |  the escaped allocas are allocated, which would break attempts to use | ||||||
|  '``llvm.localrecover``'. |  '``llvm.localrecover``'. | ||||||
|   |   | ||||||
| @@ -683,7 +941,7 @@ index 9b58b9dfb17..1738ccd94ee 100644 | |||||||
| +-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mark _try | +-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mark _try | ||||||
| +boundary and to prevent from potential exceptions being moved across boundary. | +boundary and to prevent from potential exceptions being moved across boundary. | ||||||
| + | + | ||||||
| +'``llvm.eha.scope.begin``' and '``llvm.eha.scope.end``' Intrinsics | +'``llvm.seh.scope.begin``' and '``llvm.seh.scope.end``' Intrinsics | ||||||
| +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
| + | + | ||||||
| +Syntax: | +Syntax: | ||||||
| @@ -691,32 +949,39 @@ index 9b58b9dfb17..1738ccd94ee 100644 | |||||||
| + | + | ||||||
| +:: | +:: | ||||||
| + | + | ||||||
| +      declare void @llvm.eha.scope.begin() | +      declare void @llvm.seh.scope.begin() | ||||||
| +      declare void @llvm.eha.scope.end() | +      declare void @llvm.seh.scope.end() | ||||||
| + | + | ||||||
| +Overview: | +Overview: | ||||||
| +""""""""" | +""""""""" | ||||||
| + | + | ||||||
| +The '``llvm.eha.scope.begin``' and '``llvm.eha.scope.end``' intrinsics mark | +The '``llvm.seh.scope.begin``' and '``llvm.seh.scope.end``' intrinsics mark | ||||||
| +the boundary of a CPP object lifetime for Windows SEH Asynchrous Exception | +the boundary of a CPP object lifetime for Windows SEH Asynchrous Exception | ||||||
| +Handling (MSVC option -EHa). | +Handling (MSVC option -EHa). | ||||||
| + | + | ||||||
| +Semantics: | +Semantics: | ||||||
| +"""""""""" | +"""""""""" | ||||||
| + | + | ||||||
| +'``llvm.eha.scope.begin``' is added immediately after an object constructor is | +LLVM's ordinary exception-handling representation associates EH cleanups and | ||||||
| +called, i.e., EHStack is not empty. So it will be an invoke, not a call. | +handlers only with ``invoke``s, which normally correspond only to call sites.  To | ||||||
| +With that it's also guaranteed that an associated EH-cleanup-pad is | +support arbitrary faulting instructions, it must be possible to recover the current | ||||||
| +created in IR regardless whether there exists a call in this object lifetime. | +EH scope for any instruction.  Turning every operation in LLVM that could fault | ||||||
| +'``llvm.eha.scope.end``' is added before the object destructor. | +into an ``invoke`` of a new, potentially-throwing intrinsic would require adding a | ||||||
| +These intrinsics make Block-level State computation possible in downstream | +large number of intrinsics, impede optimization of those operations, and make | ||||||
| +LLVM code gen pass, even in the presence of ctor/dtor inlining. | +compilation slower by introducing many extra basic blocks.  These intrinsics can | ||||||
|  | +be used instead to mark the region protected by a cleanup, such as for a local | ||||||
|  | +C++ object with a non-trivial destructor.  ``llvm.seh.scope.begin`` is used to mark | ||||||
|  | +the start of the region; it is aways called with ``invoke``, with the unwind block | ||||||
|  | +being the desired unwind destination for any potentially-throwing instructions | ||||||
|  | +within the region.  `llvm.seh.scope.end` is used to mark when the scope ends | ||||||
|  | +and the EH cleanup is no longer required (e.g. because the destructor is being | ||||||
|  | +called). | ||||||
| + | + | ||||||
|  .. _int_read_register: |  .. _int_read_register: | ||||||
|  .. _int_read_volatile_register: |  .. _int_read_volatile_register: | ||||||
|  .. _int_write_register: |  .. _int_write_register: | ||||||
| diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td | diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td | ||||||
| index 4918ea876df..7de760291d9 100644 | index 4918ea876df..0d33b64998d 100644 | ||||||
| --- a/llvm/include/llvm/IR/Intrinsics.td | --- a/llvm/include/llvm/IR/Intrinsics.td | ||||||
| +++ b/llvm/include/llvm/IR/Intrinsics.td | +++ b/llvm/include/llvm/IR/Intrinsics.td | ||||||
| @@ -481,6 +481,16 @@ def int_eh_recoverfp : Intrinsic<[llvm_ptr_ty], | @@ -481,6 +481,16 @@ def int_eh_recoverfp : Intrinsic<[llvm_ptr_ty], | ||||||
| @@ -730,14 +995,14 @@ index 4918ea876df..7de760291d9 100644 | |||||||
| +//   after EH tables are generated | +//   after EH tables are generated | ||||||
| +def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>; | +def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>; | ||||||
| +def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>; | +def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>; | ||||||
| +def int_eha_scope_begin : Intrinsic<[], [], [IntrNoMem]>; | +def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>; | ||||||
| +def int_eha_scope_end : Intrinsic<[], [], [IntrNoMem]>; | +def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>; | ||||||
| + | + | ||||||
|  // Note: we treat stacksave/stackrestore as writemem because we don't otherwise |  // Note: we treat stacksave/stackrestore as writemem because we don't otherwise | ||||||
|  // model their dependencies on allocas. |  // model their dependencies on allocas. | ||||||
|  def int_stacksave     : Intrinsic<[llvm_ptr_ty]>, |  def int_stacksave     : Intrinsic<[llvm_ptr_ty]>, | ||||||
| diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | ||||||
| index d2930391f87..7e58de39962 100644 | index d2930391f87..0e5a78f314b 100644 | ||||||
| --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | ||||||
| +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | ||||||
| @@ -2801,6 +2801,10 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { | @@ -2801,6 +2801,10 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { | ||||||
| @@ -745,9 +1010,9 @@ index d2930391f87..7e58de39962 100644 | |||||||
|      case Intrinsic::donothing: |      case Intrinsic::donothing: | ||||||
|        // Ignore invokes to @llvm.donothing: jump directly to the next BB. |        // Ignore invokes to @llvm.donothing: jump directly to the next BB. | ||||||
| +    case Intrinsic::seh_try_begin: | +    case Intrinsic::seh_try_begin: | ||||||
| +    case Intrinsic::eha_scope_begin: | +    case Intrinsic::seh_scope_begin: | ||||||
| +    case Intrinsic::seh_try_end: | +    case Intrinsic::seh_try_end: | ||||||
| +    case Intrinsic::eha_scope_end: | +    case Intrinsic::seh_scope_end: | ||||||
|        break; |        break; | ||||||
|      case Intrinsic::experimental_patchpoint_void: |      case Intrinsic::experimental_patchpoint_void: | ||||||
|      case Intrinsic::experimental_patchpoint_i64: |      case Intrinsic::experimental_patchpoint_i64: | ||||||
| @@ -756,14 +1021,14 @@ index d2930391f87..7e58de39962 100644 | |||||||
|      return; |      return; | ||||||
|    case Intrinsic::donothing: |    case Intrinsic::donothing: | ||||||
| +  case Intrinsic::seh_try_begin: | +  case Intrinsic::seh_try_begin: | ||||||
| +  case Intrinsic::eha_scope_begin: | +  case Intrinsic::seh_scope_begin: | ||||||
| +  case Intrinsic::seh_try_end: | +  case Intrinsic::seh_try_end: | ||||||
| +  case Intrinsic::eha_scope_end: | +  case Intrinsic::seh_scope_end: | ||||||
|      // ignore |      // ignore | ||||||
|      return; |      return; | ||||||
|    case Intrinsic::experimental_stackmap: |    case Intrinsic::experimental_stackmap: | ||||||
| diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp | diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp | ||||||
| index c518ae87ea9..87dd063ee2e 100644 | index c518ae87ea9..6fb5e60c34a 100644 | ||||||
| --- a/llvm/lib/IR/Verifier.cpp | --- a/llvm/lib/IR/Verifier.cpp | ||||||
| +++ b/llvm/lib/IR/Verifier.cpp | +++ b/llvm/lib/IR/Verifier.cpp | ||||||
| @@ -4269,6 +4269,10 @@ void Verifier::visitInstruction(Instruction &I) { | @@ -4269,6 +4269,10 @@ void Verifier::visitInstruction(Instruction &I) { | ||||||
| @@ -772,8 +1037,8 @@ index c518ae87ea9..87dd063ee2e 100644 | |||||||
|                F->getIntrinsicID() == Intrinsic::donothing || |                F->getIntrinsicID() == Intrinsic::donothing || | ||||||
| +              F->getIntrinsicID() == Intrinsic::seh_try_begin || | +              F->getIntrinsicID() == Intrinsic::seh_try_begin || | ||||||
| +              F->getIntrinsicID() == Intrinsic::seh_try_end || | +              F->getIntrinsicID() == Intrinsic::seh_try_end || | ||||||
| +              F->getIntrinsicID() == Intrinsic::eha_scope_begin || | +              F->getIntrinsicID() == Intrinsic::seh_scope_begin || | ||||||
| +              F->getIntrinsicID() == Intrinsic::eha_scope_end || | +              F->getIntrinsicID() == Intrinsic::seh_scope_end || | ||||||
|                F->getIntrinsicID() == Intrinsic::coro_resume || |                F->getIntrinsicID() == Intrinsic::coro_resume || | ||||||
|                F->getIntrinsicID() == Intrinsic::coro_destroy || |                F->getIntrinsicID() == Intrinsic::coro_destroy || | ||||||
|                F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || |                F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user