diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1787,13 +1787,22 @@ LLVM_PointerTo:$ptr, LLVM_AtomicRMWType:$val, AtomicOrdering:$ordering); let results = (outs LLVM_AtomicRMWType:$res); - let llvmBuilder = [{ + let hasCustomAssemblyFormat = 1; + let hasVerifier = 1; + string llvmInstName = "AtomicRMW"; + string llvmBuilder = [{ $res = builder.CreateAtomicRMW(getLLVMAtomicBinOp($bin_op), $ptr, $val, llvm::MaybeAlign(), getLLVMAtomicOrdering($ordering)); }]; - let hasCustomAssemblyFormat = 1; - let hasVerifier = 1; + string mlirBuilder = [{ + auto *atomicInst = cast(inst); + $res = $_builder.create($_location, $_resultType, + getLLVMAtomicBinOp(atomicInst->getOperation()), $ptr, $val, + getLLVMAtomicOrdering(atomicInst->getOrdering())); + }]; + // Only $ptr and $val are llvm instruction operands. + list llvmArgIndices = [-1, 0, 1, -1]; } def LLVM_AtomicCmpXchgType : AnyTypeOf<[AnyInteger, LLVM_AnyPointer]>; @@ -1816,13 +1825,21 @@ AtomicOrdering:$success_ordering, AtomicOrdering:$failure_ordering); let results = (outs LLVM_AtomicCmpXchgResultType:$res); - let llvmBuilder = [{ + let hasCustomAssemblyFormat = 1; + let hasVerifier = 1; + string llvmInstName = "AtomicCmpXchg"; + string llvmBuilder = [{ $res = builder.CreateAtomicCmpXchg($ptr, $cmp, $val, llvm::MaybeAlign(), getLLVMAtomicOrdering($success_ordering), getLLVMAtomicOrdering($failure_ordering)); }]; - let hasCustomAssemblyFormat = 1; - let hasVerifier = 1; + string mlirBuilder = [{ + auto *cmpXchgInst = cast(inst); + $res = $_builder.create( + $_location, $_resultType, $ptr, $cmp, $val, + getLLVMAtomicOrdering(cmpXchgInst->getSuccessOrdering()), + getLLVMAtomicOrdering(cmpXchgInst->getFailureOrdering())); + }]; } def LLVM_FenceOp : LLVM_Op<"fence"> { diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -941,37 +941,6 @@ mapValue(inst, op->getResult(0)); return success(); } - if (inst->getOpcode() == llvm::Instruction::AtomicRMW) { - auto *atomicInst = cast(inst); - Value ptr = processValue(atomicInst->getPointerOperand()); - Value val = processValue(atomicInst->getValOperand()); - - LLVM::AtomicBinOp binOp = getLLVMAtomicBinOp(atomicInst->getOperation()); - LLVM::AtomicOrdering ordering = - getLLVMAtomicOrdering(atomicInst->getOrdering()); - - Type type = convertType(inst->getType()); - Value res = b.create(loc, type, binOp, ptr, val, ordering); - mapValue(inst, res); - return success(); - } - if (inst->getOpcode() == llvm::Instruction::AtomicCmpXchg) { - auto *cmpXchgInst = cast(inst); - Value ptr = processValue(cmpXchgInst->getPointerOperand()); - Value cmpVal = processValue(cmpXchgInst->getCompareOperand()); - Value newVal = processValue(cmpXchgInst->getNewValOperand()); - - LLVM::AtomicOrdering ordering = - getLLVMAtomicOrdering(cmpXchgInst->getSuccessOrdering()); - LLVM::AtomicOrdering failOrdering = - getLLVMAtomicOrdering(cmpXchgInst->getFailureOrdering()); - - Type type = convertType(inst->getType()); - Value res = b.create(loc, type, ptr, cmpVal, newVal, - ordering, failOrdering); - mapValue(inst, res); - return success(); - } if (inst->getOpcode() == llvm::Instruction::GetElementPtr) { // FIXME: Support inbounds GEPs. llvm::GetElementPtrInst *gep = cast(inst); diff --git a/mlir/test/Target/LLVMIR/Import/basic.ll b/mlir/test/Target/LLVMIR/Import/basic.ll --- a/mlir/test/Target/LLVMIR/Import/basic.ll +++ b/mlir/test/Target/LLVMIR/Import/basic.ll @@ -478,46 +478,3 @@ ; CHECK: llvm.return ret void } - -; CHECK-LABEL: llvm.func @atomic_rmw -define void @atomic_rmw(i32* %ptr0, i32 %v, float* %ptr1, float %f) { - ; CHECK: llvm.atomicrmw add %arg0, %arg1 acquire : i32 - %1 = atomicrmw add i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw add %arg0, %arg1 release : i32 - %2 = atomicrmw add i32* %ptr0, i32 %v release - - ; CHECK: llvm.atomicrmw sub %arg0, %arg1 acquire : i32 - %3 = atomicrmw sub i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw xchg %arg0, %arg1 acquire : i32 - %4 = atomicrmw xchg i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw _and %arg0, %arg1 acquire : i32 - %5 = atomicrmw and i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw nand %arg0, %arg1 acquire : i32 - %6 = atomicrmw nand i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw _or %arg0, %arg1 acquire : i32 - %7 = atomicrmw or i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw _xor %arg0, %arg1 acquire : i32 - %8 = atomicrmw xor i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw max %arg0, %arg1 acquire : i32 - %9 = atomicrmw max i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw min %arg0, %arg1 acquire : i32 - %10 = atomicrmw min i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw umax %arg0, %arg1 acquire : i32 - %11 = atomicrmw umax i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw umin %arg0, %arg1 acquire : i32 - %12 = atomicrmw umin i32* %ptr0, i32 %v acquire - ; CHECK: llvm.atomicrmw fadd %arg2, %arg3 acquire : f32 - %13 = atomicrmw fadd float* %ptr1, float %f acquire - ; CHECK: llvm.atomicrmw fsub %arg2, %arg3 acquire : f32 - %14 = atomicrmw fsub float* %ptr1, float %f acquire - ret void -} - -; CHECK-LABEL: llvm.func @atomic_cmpxchg -define void @atomic_cmpxchg(i32* %ptr0, i32 %v, i32 %c) { - ; CHECK: llvm.cmpxchg %arg0, %arg2, %arg1 seq_cst seq_cst : i32 - %1 = cmpxchg i32* %ptr0, i32 %c, i32 %v seq_cst seq_cst - ; CHECK: llvm.cmpxchg %arg0, %arg2, %arg1 monotonic seq_cst : i32 - %2 = cmpxchg i32* %ptr0, i32 %c, i32 %v monotonic seq_cst - ret void -} diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll --- a/mlir/test/Target/LLVMIR/Import/instructions.ll +++ b/mlir/test/Target/LLVMIR/Import/instructions.ll @@ -361,6 +361,57 @@ ; // ----- +; CHECK-LABEL: @atomic_rmw +; CHECK-SAME: %[[PTR1:[a-zA-Z0-9]+]] +; CHECK-SAME: %[[VAL1:[a-zA-Z0-9]+]] +; CHECK-SAME: %[[PTR2:[a-zA-Z0-9]+]] +; CHECK-SAME: %[[VAL2:[a-zA-Z0-9]+]] +define void @atomic_rmw(i32* %ptr1, i32 %val1, float* %ptr2, float %val2) { + ; CHECK: llvm.atomicrmw xchg %[[PTR1]], %[[VAL1]] acquire : i32 + %1 = atomicrmw xchg i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw add %[[PTR1]], %[[VAL1]] release : i32 + %2 = atomicrmw add i32* %ptr1, i32 %val1 release + ; CHECK: llvm.atomicrmw sub %[[PTR1]], %[[VAL1]] acq_rel : i32 + %3 = atomicrmw sub i32* %ptr1, i32 %val1 acq_rel + ; CHECK: llvm.atomicrmw _and %[[PTR1]], %[[VAL1]] seq_cst : i32 + %4 = atomicrmw and i32* %ptr1, i32 %val1 seq_cst + ; CHECK: llvm.atomicrmw nand %[[PTR1]], %[[VAL1]] acquire : i32 + %5 = atomicrmw nand i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw _or %[[PTR1]], %[[VAL1]] acquire : i32 + %6 = atomicrmw or i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw _xor %[[PTR1]], %[[VAL1]] acquire : i32 + %7 = atomicrmw xor i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw max %[[PTR1]], %[[VAL1]] acquire : i32 + %8 = atomicrmw max i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw min %[[PTR1]], %[[VAL1]] acquire : i32 + %9 = atomicrmw min i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw umax %[[PTR1]], %[[VAL1]] acquire : i32 + %10 = atomicrmw umax i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw umin %[[PTR1]], %[[VAL1]] acquire : i32 + %11 = atomicrmw umin i32* %ptr1, i32 %val1 acquire + ; CHECK: llvm.atomicrmw fadd %[[PTR2]], %[[VAL2]] acquire : f32 + %12 = atomicrmw fadd float* %ptr2, float %val2 acquire + ; CHECK: llvm.atomicrmw fsub %[[PTR2]], %[[VAL2]] acquire : f32 + %13 = atomicrmw fsub float* %ptr2, float %val2 acquire + ret void +} + +; // ----- + +; CHECK-LABEL: @atomic_cmpxchg +; CHECK-SAME: %[[PTR1:[a-zA-Z0-9]+]] +; CHECK-SAME: %[[VAL1:[a-zA-Z0-9]+]] +; CHECK-SAME: %[[VAL2:[a-zA-Z0-9]+]] +define void @atomic_cmpxchg(i32* %ptr1, i32 %val1, i32 %val2) { + ; CHECK: llvm.cmpxchg %[[PTR1]], %[[VAL1]], %[[VAL2]] seq_cst seq_cst : i32 + %1 = cmpxchg i32* %ptr1, i32 %val1, i32 %val2 seq_cst seq_cst + ; CHECK: llvm.cmpxchg %[[PTR1]], %[[VAL1]], %[[VAL2]] monotonic seq_cst : i32 + %2 = cmpxchg i32* %ptr1, i32 %val1, i32 %val2 monotonic seq_cst + ret void +} + +; // ----- + ; CHECK-LABEL: @freeze ; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]] define void @freeze(i32 %arg1) {