llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Erich Keane (erichkeane)

<details>
<summary>Changes</summary>

This mirrors what LLVM does, and requires propagating into the LLVM dialect: 
When the user specifies 'noreturn' we propagate this down throughout the stack.

Note the similar 'willreturn' is too strong of a guarantee (in that they are 
not opposites of each other, as there is a 'unknown' implied by all others), so 
we cannot use that on non-noreturn functions.

---

Patch is 22.42 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/177978.diff


13 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.td (+1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+40-8) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+22-4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+5-6) 
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+1-1) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+11-2) 
- (added) clang/test/CIR/CodeGen/noreturn.cpp (+49) 
- (modified) clang/test/CIR/CodeGenBuiltins/builtin_call.cpp (+1-1) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+2) 
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+4) 
- (modified) mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp 
(+2) 
- (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+1) 
- (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+2) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 7c38492544b39..058f096bfae3b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -39,6 +39,7 @@ def CIR_Dialect : Dialect {
     static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
     static llvm::StringRef getCalleeAttrName() { return "callee"; }
     static llvm::StringRef getNoThrowAttrName() { return "nothrow"; }
+    static llvm::StringRef getNoReturnAttrName() { return "no_return"; }
     static llvm::StringRef getSideEffectAttrName() { return "side_effect"; }
     static llvm::StringRef getModuleLevelAsmAttrName() { return 
"cir.module_asm"; }
     static llvm::StringRef getGlobalCtorsAttrName() { return 
"cir.global_ctors"; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 5fd11c6d97c07..628f39ae2cfba 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -21,7 +21,7 @@ using namespace clang;
 using namespace clang::CIRGen;
 
 CIRGenFunctionInfo *
-CIRGenFunctionInfo::create(CanQualType resultType,
+CIRGenFunctionInfo::create(FunctionType::ExtInfo info, CanQualType resultType,
                            llvm::ArrayRef<CanQualType> argTypes,
                            RequiredArgs required) {
   // The first slot allocated for arg type slot is for the return value.
@@ -32,6 +32,8 @@ CIRGenFunctionInfo::create(CanQualType resultType,
 
   CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo();
 
+  fi->noReturn = info.getNoReturn();
+
   fi->required = required;
   fi->numArgs = argTypes.size();
 
@@ -120,6 +122,11 @@ void CIRGenModule::constructAttributeList(llvm::StringRef 
name,
   assert(!cir::MissingFeatures::opCallCallConv());
   sideEffect = cir::SideEffect::All;
 
+  if (info.isNoReturn())
+    attrs.set(cir::CIRDialect::getNoReturnAttrName(),
+              mlir::UnitAttr::get(&getMLIRContext()));
+  // TODO(cir): Check/add cmse_nonsecure_call attribute here.
+
   addAttributesFromFunctionProtoType(getBuilder(), attrs,
                                      calleeInfo.getCalleeFunctionProtoType());
 
@@ -129,11 +136,30 @@ void CIRGenModule::constructAttributeList(llvm::StringRef 
name,
     if (targetDecl->hasAttr<NoThrowAttr>())
       attrs.set(cir::CIRDialect::getNoThrowAttrName(),
                 mlir::UnitAttr::get(&getMLIRContext()));
+    // TODO(cir): This is actually only possible if targetDecl isn't a
+    // declarator, which ObjCMethodDecl seems to be the only way to get this to
+    // happen.  We're including it here for completeness, but we should add a
+    // test for this when we start generating ObjectiveC.
+    if (targetDecl->hasAttr<NoReturnAttr>())
+      attrs.set(cir::CIRDialect::getNoReturnAttrName(),
+                mlir::UnitAttr::get(&getMLIRContext()));
 
     if (const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
       addAttributesFromFunctionProtoType(
           getBuilder(), attrs, func->getType()->getAs<FunctionProtoType>());
       assert(!cir::MissingFeatures::opCallAttrs());
+
+      const CXXMethodDecl *md = dyn_cast<CXXMethodDecl>(func);
+      bool isVirtualCall = md && md->isVirtual();
+
+      // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a
+      // virtual function. These attributes are not inherited by overloads.
+      if (!(attrOnCallSite && isVirtualCall)) {
+        if (func->isNoReturn())
+          attrs.set(cir::CIRDialect::getNoReturnAttrName(),
+                    mlir::UnitAttr::get(&getMLIRContext()));
+        // TODO(cir): Set NoBuiltinAttr here.
+      }
     }
 
     assert(!cir::MissingFeatures::opCallAttrs());
@@ -222,7 +248,8 @@ CIRGenTypes::arrangeCXXStructorDeclaration(GlobalDecl gd) {
   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
   assert(!cir::MissingFeatures::opCallFnInfoOpts());
 
-  return arrangeCIRFunctionInfo(resultType, argTypes, required);
+  return arrangeCIRFunctionInfo(fpt->getExtInfo(), resultType, argTypes,
+                                required);
 }
 
 /// Derives the 'this' type for CIRGen purposes, i.e. ignoring method CVR
@@ -259,7 +286,8 @@ arrangeCIRFunctionInfo(CIRGenTypes &cgt, 
SmallVectorImpl<CanQualType> &prefix,
   assert(!cir::MissingFeatures::opCallExtParameterInfo());
   appendParameterTypes(cgt, prefix, fpt);
   CanQualType resultType = fpt->getReturnType().getUnqualifiedType();
-  return cgt.arrangeCIRFunctionInfo(resultType, prefix, required);
+  return cgt.arrangeCIRFunctionInfo(fpt->getExtInfo(), resultType, prefix,
+                                    required);
 }
 
 void CIRGenFunction::emitDelegateCallArg(CallArgList &args,
@@ -325,7 +353,8 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule 
&cgm,
   CanQualType retType = fnType->getReturnType()->getCanonicalTypeUnqualified();
 
   assert(!cir::MissingFeatures::opCallFnInfoOpts());
-  return cgt.arrangeCIRFunctionInfo(retType, argTypes, required);
+  return cgt.arrangeCIRFunctionInfo(fnType->getExtInfo(), retType, argTypes,
+                                    required);
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
@@ -364,7 +393,8 @@ const CIRGenFunctionInfo 
&CIRGenTypes::arrangeCXXConstructorCall(
   assert(!cir::MissingFeatures::opCallFnInfoOpts());
   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
 
-  return arrangeCIRFunctionInfo(resultType, argTypes, required);
+  return arrangeCIRFunctionInfo(fpt->getExtInfo(), resultType, argTypes,
+                                required);
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
@@ -385,6 +415,7 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXMethodCall(
 
   assert(!cir::MissingFeatures::opCallFnInfoOpts());
   return arrangeCIRFunctionInfo(
+      proto->getExtInfo(),
       proto->getReturnType()->getCanonicalTypeUnqualified(), argTypes,
       required);
 }
@@ -456,8 +487,8 @@ CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl 
*fd) {
           funcTy.getAs<FunctionNoProtoType>()) {
     assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
     assert(!cir::MissingFeatures::opCallFnInfoOpts());
-    return arrangeCIRFunctionInfo(noProto->getReturnType(), {},
-                                  RequiredArgs::All);
+    return arrangeCIRFunctionInfo(
+        noProto->getExtInfo(), noProto->getReturnType(), {}, 
RequiredArgs::All);
   }
 
   return arrangeFreeFunctionType(funcTy.castAs<FunctionProtoType>());
@@ -535,7 +566,8 @@ const CIRGenFunctionInfo &
 CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> fnpt) {
   CanQualType resultType = fnpt->getReturnType().getUnqualifiedType();
   assert(!cir::MissingFeatures::opCallFnInfoOpts());
-  return arrangeCIRFunctionInfo(resultType, {}, RequiredArgs(0));
+  return arrangeCIRFunctionInfo(fnpt->getExtInfo(), resultType, {},
+                                RequiredArgs(0));
 }
 
 RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h 
b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index 4f5754cb43986..fb7da9e414139 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -72,6 +72,10 @@ class RequiredArgs {
 class CIRGenFunctionInfo final
     : public llvm::FoldingSetNode,
       private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {
+  // Whether this function has noreturn.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned noReturn : 1;
+
   RequiredArgs required;
 
   unsigned numArgs;
@@ -81,8 +85,19 @@ class CIRGenFunctionInfo final
 
   CIRGenFunctionInfo() : required(RequiredArgs::All) {}
 
+  FunctionType::ExtInfo getExtInfo() const {
+    // TODO(cir): as we add this information to this type, we need to add calls
+    // here instead of explicit false/0.
+    return FunctionType::ExtInfo(
+        isNoReturn(), /*getHasRegParm=*/false, /*getRegParm=*/false,
+        /*getASTCallingConvention=*/CallingConv(0), 
/*isReturnsRetained=*/false,
+        /*isNoCallerSavedRegs=*/false, /*isNoCfCheck=*/false,
+        /*isCmseNSCall=*/false);
+  }
+
 public:
-  static CIRGenFunctionInfo *create(CanQualType resultType,
+  static CIRGenFunctionInfo *create(FunctionType::ExtInfo info,
+                                    CanQualType resultType,
                                     llvm::ArrayRef<CanQualType> argTypes,
                                     RequiredArgs required);
 
@@ -97,9 +112,10 @@ class CIRGenFunctionInfo final
 
   // This function has to be CamelCase because llvm::FoldingSet requires so.
   // NOLINTNEXTLINE(readability-identifier-naming)
-  static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required,
-                      CanQualType resultType,
+  static void Profile(llvm::FoldingSetNodeID &id, FunctionType::ExtInfo info,
+                      RequiredArgs required, CanQualType resultType,
                       llvm::ArrayRef<CanQualType> argTypes) {
+    id.AddBoolean(info.getNoReturn());
     id.AddBoolean(required.getOpaqueData());
     resultType.Profile(id);
     for (const CanQualType &arg : argTypes)
@@ -111,7 +127,7 @@ class CIRGenFunctionInfo final
     // If the Profile functions get out of sync, we can end up with incorrect
     // function signatures, so we call the static Profile function here rather
     // than duplicating the logic.
-    Profile(id, required, getReturnType(), arguments());
+    Profile(id, getExtInfo(), required, getReturnType(), arguments());
   }
 
   llvm::ArrayRef<CanQualType> arguments() const {
@@ -144,6 +160,8 @@ class CIRGenFunctionInfo final
     return isVariadic() ? getRequiredArgs().getNumRequiredArgs()
                         : argTypeSize();
   }
+
+  bool isNoReturn() const { return noReturn; }
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 610ee2ceb1da4..1b0aad37569c4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -662,15 +662,14 @@ bool CIRGenTypes::isZeroInitializable(const RecordDecl 
*rd) {
   return getCIRGenRecordLayout(rd).isZeroInitializable();
 }
 
-const CIRGenFunctionInfo &
-CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType,
-                                    llvm::ArrayRef<CanQualType> argTypes,
-                                    RequiredArgs required) {
+const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
+    FunctionType::ExtInfo info, CanQualType returnType,
+    llvm::ArrayRef<CanQualType> argTypes, RequiredArgs required) {
   assert(llvm::all_of(argTypes,
                       [](CanQualType t) { return t.isCanonicalAsParam(); }));
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID id;
-  CIRGenFunctionInfo::Profile(id, required, returnType, argTypes);
+  CIRGenFunctionInfo::Profile(id, info, required, returnType, argTypes);
 
   void *insertPos = nullptr;
   CIRGenFunctionInfo *fi = functionInfos.FindNodeOrInsertPos(id, insertPos);
@@ -687,7 +686,7 @@ CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType,
   assert(!cir::MissingFeatures::opCallCallConv());
 
   // Construction the function info. We co-allocate the ArgInfos.
-  fi = CIRGenFunctionInfo::create(returnType, argTypes, required);
+  fi = CIRGenFunctionInfo::create(info, returnType, argTypes, required);
   functionInfos.InsertNode(fi, insertPos);
 
   return *fi;
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h 
b/clang/lib/CIR/CodeGen/CIRGenTypes.h
index e79cdfc9f8224..bbc594c8656da 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h
@@ -197,7 +197,7 @@ class CIRGenTypes {
                                                     const FunctionType 
*fnType);
 
   const CIRGenFunctionInfo &
-  arrangeCIRFunctionInfo(CanQualType returnType,
+  arrangeCIRFunctionInfo(FunctionType::ExtInfo info, CanQualType returnType,
                          llvm::ArrayRef<CanQualType> argTypes,
                          RequiredArgs required);
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4877508b1c3da..20bfb6c3153e1 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -310,7 +310,8 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp,
 void convertSideEffectForCall(mlir::Operation *callOp, bool isNothrow,
                               cir::SideEffect sideEffect,
                               mlir::LLVM::MemoryEffectsAttr &memoryEffect,
-                              bool &noUnwind, bool &willReturn) {
+                              bool &noUnwind, bool &willReturn,
+                              bool &noReturn) {
   using mlir::LLVM::ModRefInfo;
 
   switch (sideEffect) {
@@ -344,6 +345,8 @@ void convertSideEffectForCall(mlir::Operation *callOp, bool 
isNothrow,
     willReturn = true;
     break;
   }
+
+  noReturn = callOp->hasAttr(CIRDialect::getNoReturnAttrName());
 }
 
 static mlir::LLVM::CallIntrinsicOp
@@ -1620,8 +1623,9 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange 
callOperands,
   mlir::LLVM::MemoryEffectsAttr memoryEffects;
   bool noUnwind = false;
   bool willReturn = false;
+  bool noReturn = false;
   convertSideEffectForCall(op, call.getNothrow(), call.getSideEffect(),
-                           memoryEffects, noUnwind, willReturn);
+                           memoryEffects, noUnwind, willReturn, noReturn);
 
   mlir::LLVM::LLVMFunctionType llvmFnTy;
 
@@ -1684,6 +1688,7 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange 
callOperands,
     newOp.setMemoryEffectsAttr(memoryEffects);
   newOp.setNoUnwind(noUnwind);
   newOp.setWillReturn(willReturn);
+  newOp.setNoReturn(noReturn);
 
   return mlir::success();
 }
@@ -2036,6 +2041,7 @@ void CIRToLLVMFuncOpLowering::lowerFuncAttributes(
         attr.getName() == func.getDsoLocalAttrName() ||
         attr.getName() == func.getInlineKindAttrName() ||
         attr.getName() == func.getSideEffectAttrName() ||
+        attr.getName() == CIRDialect::getNoReturnAttrName() ||
         (filterArgAndResAttrs &&
          (attr.getName() == func.getArgAttrsAttrName() ||
           attr.getName() == func.getResAttrsAttrName())))
@@ -2151,6 +2157,9 @@ mlir::LogicalResult 
CIRToLLVMFuncOpLowering::matchAndRewrite(
     }
   }
 
+  if (op->hasAttr(CIRDialect::getNoReturnAttrName()))
+    fn.setNoReturn(true);
+
   if (std::optional<cir::InlineKind> inlineKind = op.getInlineKind()) {
     fn.setNoInline(*inlineKind == cir::InlineKind::NoInline);
     fn.setInlineHint(*inlineKind == cir::InlineKind::InlineHint);
diff --git a/clang/test/CIR/CodeGen/noreturn.cpp 
b/clang/test/CIR/CodeGen/noreturn.cpp
new file mode 100644
index 0000000000000..ddb9e25802ddb
--- /dev/null
+++ b/clang/test/CIR/CodeGen/noreturn.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+extern "C" {
+// CIR: cir.func {{.*}} @bar() -> !s32i attributes {no_return} {
+// LLVM: Function Attrs:{{.*}} noreturn
+// LLVM-NEXT: define {{.*}} i32 @bar() #[[BAR_FOO_ATTR:.*]] {
+// OGCG: Function Attrs:{{.*}} noreturn
+// OGCG-NEXT: define {{.*}} i32 @bar() #[[BAR_FOO_ATTR:.*]] {
+__attribute((noreturn))
+int bar() { }
+
+// Note: Classic codegen puts this here, so we need this to make sure the
+// FunctionAttrs from `trap` doesn't interfere with 'foo'. However, CIR->LLVM
+// lowering puts the trap decl at the end, so it isn't here to worry about.
+// OGCG: declare void @llvm.trap
+
+// CIR: cir.func {{.*}} @foo() -> !s32i attributes {no_return} {
+// LLVM: Function Attrs:{{.*}} noreturn
+// LLVM-NEXT: define {{.*}} i32 @foo() #[[BAR_FOO_ATTR:.*]] {
+// OGCG: Function Attrs:{{.*}} noreturn
+// OGCG-NEXT: define {{.*}} i32 @foo() #[[BAR_FOO_ATTR:.*]] {
+[[noreturn]]
+int foo() { }
+
+void caller() {
+  // CIR: cir.call @bar() {no_return} : () -> !s32i
+  // LLVM: call i32 @bar() #[[CALL_ATTR:.*]]
+  // OGCG: call i32 @bar() #[[CALL_ATTR:.*]]
+  bar();
+}
+
+void caller2() {
+  // CIR: cir.call @foo() {no_return} : () -> !s32i
+  // LLVM: call i32 @foo() #[[CALL_ATTR:.*]]
+  // OGCG: call i32 @foo() #[[CALL_ATTR:.*]]
+  foo();
+}
+
+// LLVM: attributes #[[BAR_FOO_ATTR]] = {{.*}}noreturn
+// OGCG: attributes #[[BAR_FOO_ATTR]] = {{.*}}noreturn
+// LLVM: attributes #[[CALL_ATTR]] = {{.*}}noreturn
+// OGCG: attributes #[[CALL_ATTR]] = {{.*}}noreturn
+
+}
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin_call.cpp 
b/clang/test/CIR/CodeGenBuiltins/builtin_call.cpp
index a08a784951247..fc9e89b0ac486 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin_call.cpp
+++ b/clang/test/CIR/CodeGenBuiltins/builtin_call.cpp
@@ -85,7 +85,7 @@ void library_builtins() {
 // CIR: cir.func{{.*}} @_Z16library_builtinsv()
 // CIR: %[[NULL:.+]] = cir.const #cir.ptr<null> : !cir.ptr<!s8i>
 // CIR: cir.call @printf(%[[NULL]]) nothrow : (!cir.ptr<!s8i>) -> !s32i
-// CIR: cir.call @abort() nothrow : () -> ()
+// CIR: cir.call @abort() nothrow {no_return} : () -> ()
 
 // LLVM: define{{.*}} void @_Z16library_builtinsv()
 // LLVM: call i32 (ptr, ...) @printf(ptr null)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 6789ca22c3d5f..b8b31680df824 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -795,6 +795,7 @@ def LLVM_CallOp
       DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$TailCallKind,
       OptionalAttr<LLVM_MemoryEffectsAttr>:$memory_effects,
       UnitAttr:$convergent, UnitAttr:$no_unwind, UnitAttr:$will_return,
+      UnitAttr:$no_return,
       VariadicOfVariadic<LLVM_Type, "op_bundle_sizes">:$op_bundle_operands,
       DenseI32ArrayAttr:$op_bundle_sizes,
       OptionalAttr<ArrayAttr>:$op_bundle_tags,
@@ -1992,6 +1993,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
     OptionalAttr<UnitAttr>:$inline_hint,
     OptionalAttr<UnitAttr>:$no_unwind,
     OptionalAttr<UnitAttr>:$will_return,
+    OptionalAttr<UnitAttr>:$no_return,
     OptionalAttr<UnitAttr>:$optimize_none,
     OptionalAttr<LLVM_VecTypeHintAttr>:$vec_type_hint,
     OptionalAttr<DenseI32ArrayAttr>:$work_group_size_hint,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp 
b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 91fbc53c5eb32..e0b751fc55664 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -995,6 +995,7 @@ void CallOp::build(OpBuilder &builder, OperationState 
&state, TypeRange results,
         /*CConv=*/nullptr, /*TailCallKind=*/nullptr,
         /*memory_effects=*/nullptr,
         /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
+        /*no_return=*/nullptr,
         /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
         /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
@@ -1025,6 +1026,7 @@ void CallOp::build(OpBuilder &builder, OperationState 
&state,
         /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr,
         /*convergent=*/nullptr,
         /*no_unwind=*/nullptr, /*will_return=*/nullptr,
+        /*no_return=*/nullptr,
         /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
         /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr,
         /*access_groups=*/nullptr,
@@ -1041,6 +1043,7 @@ void CallOp::build(OpBuilder &builder, OperationState 
&state,
         /*fastmathFlags=*/nullptr,
         /*CConv=*/nullptr, /*TailCallKind=*/nullptr, 
/*memory_effects=*/nullptr,
         /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
+        /*no_return=*/nullptr,
         /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
         /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
@@ -1057,6 +1060,7 @@ void CallOp::build(OpBuilder &builder, OperationState 
&state, LLVMFuncOp func,
 ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/177978
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to