diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -49,6 +49,7 @@ static StringRef getByRefAttrName() { return "llvm.byref"; } static StringRef getStructRetAttrName() { return "llvm.sret"; } static StringRef getInAllocaAttrName() { return "llvm.inalloca"; } + static StringRef getNoUndefAttrName() { return "llvm.noundef"; } /// Verifies if the attribute is a well-formed value for "llvm.struct_attrs" static LogicalResult verifyStructAttr( diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -917,6 +917,13 @@ .addAttribute(llvm::Attribute::Nest)); } + if (auto attr = func.getArgAttrOfType( + argIdx, LLVMDialect::getNoUndefAttrName())) { + // llvm.noundef can be added to any argument type. + llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext()) + .addAttribute(llvm::Attribute::NoUndef)); + } + mapValue(mlirArg, &llvmArg); argIdx++; } diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -1064,6 +1064,11 @@ llvm.return } +// CHECK-LABEL: define void @noundefattr(i32 noundef % +llvm.func @noundefattr(%arg0: i32 {llvm.noundef}) { + llvm.return +} + // CHECK-LABEL: define void @llvm_align(ptr align 4 {{%*.}}) llvm.func @llvm_align(%arg0: !llvm.ptr {llvm.align = 4}) { llvm.return