diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index cff5a1940e77e..f24c2777cbbb8 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2263,10 +2263,15 @@ LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst, LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst, CallOp op) { setFastmathFlagsAttr(inst, op.getOperation()); + // Query the attributes directly instead of using `inst->getFnAttr(Kind)`, the + // latter does additional lookup to the parent and inherits, changing the + // semantics too early. + llvm::AttributeList callAttrs = inst->getAttributes(); + op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind())); - op.setConvergent(inst->isConvergent()); - op.setNoUnwind(inst->doesNotThrow()); - op.setWillReturn(inst->hasFnAttr(llvm::Attribute::WillReturn)); + op.setConvergent(callAttrs.getFnAttr(llvm::Attribute::Convergent).isValid()); + op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid()); + op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid()); llvm::MemoryEffects memEffects = inst->getMemoryEffects(); ModRefInfo othermem = convertModRefInfoFromLLVM( diff --git a/mlir/test/Target/LLVMIR/Import/call-argument-attributes.ll b/mlir/test/Target/LLVMIR/Import/call-argument-attributes.ll index fa39c79bf0859..842639df0d44b 100644 --- a/mlir/test/Target/LLVMIR/Import/call-argument-attributes.ll +++ b/mlir/test/Target/LLVMIR/Import/call-argument-attributes.ll @@ -1,4 +1,4 @@ -; RUN: mlir-translate -import-llvm %s | FileCheck %s +; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s ; CHECK-LABEL: llvm.func @somefunc(i32, !llvm.ptr) declare void @somefunc(i32, ptr) @@ -20,3 +20,22 @@ define i16 @test_call_arg_attrs_indirect(i16 %0, ptr %1) { %3 = tail call signext i16 %1(i16 noundef signext %0) ret i16 %3 } + +; // ----- + +%struct.S = type { i8 } + +; CHECK-LABEL: @t +define void @t(i1 %0) #0 { + %3 = alloca %struct.S, align 1 + ; CHECK-NOT: llvm.call @z(%1) {no_unwind} : (!llvm.ptr) -> () + ; CHECK: llvm.call @z(%1) : (!llvm.ptr) -> () + call void @z(ptr %3) + ret void +} + +define linkonce_odr void @z(ptr %0) #0 { + ret void +} + +attributes #0 = { nounwind }