@@ -1623,31 +1623,33 @@ convertOmpAtomicUpdate(omp::AtomicUpdateOp &opInst,
1623
1623
1624
1624
// Convert values and types.
1625
1625
auto &innerOpList = opInst.getRegion ().front ().getOperations ();
1626
- bool isRegionArgUsed{ false }, isXBinopExpr{false };
1626
+ bool isXBinopExpr{false };
1627
1627
llvm::AtomicRMWInst::BinOp binop;
1628
1628
mlir::Value mlirExpr;
1629
- // Find the binary update operation that uses the region argument
1630
- // and get the expression to update
1631
- for (Operation &innerOp : innerOpList) {
1632
- if (innerOp.getNumOperands () == 2 ) {
1633
- binop = convertBinOpToAtomic (innerOp);
1634
- if (!llvm::is_contained (innerOp.getOperands (),
1635
- opInst.getRegion ().getArgument (0 )))
1636
- continue ;
1637
- isRegionArgUsed = true ;
1638
- isXBinopExpr = innerOp.getNumOperands () > 0 &&
1639
- innerOp.getOperand (0 ) == opInst.getRegion ().getArgument (0 );
1640
- mlirExpr = (isXBinopExpr ? innerOp.getOperand (1 ) : innerOp.getOperand (0 ));
1641
- break ;
1629
+ llvm::Value *llvmExpr = nullptr ;
1630
+ llvm::Value *llvmX = nullptr ;
1631
+ llvm::Type *llvmXElementType = nullptr ;
1632
+ if (innerOpList.size () == 2 ) {
1633
+ // The two operations here are the update and the terminator.
1634
+ // Since we can identify the update operation, there is a possibility
1635
+ // that we can generate the atomicrmw instruction.
1636
+ mlir::Operation &innerOp = *opInst.getRegion ().front ().begin ();
1637
+ if (!llvm::is_contained (innerOp.getOperands (),
1638
+ opInst.getRegion ().getArgument (0 ))) {
1639
+ return opInst.emitError (" no atomic update operation with region argument"
1640
+ " as operand found inside atomic.update region" );
1642
1641
}
1642
+ binop = convertBinOpToAtomic (innerOp);
1643
+ isXBinopExpr = innerOp.getOperand (0 ) == opInst.getRegion ().getArgument (0 );
1644
+ mlirExpr = (isXBinopExpr ? innerOp.getOperand (1 ) : innerOp.getOperand (0 ));
1645
+ llvmExpr = moduleTranslation.lookupValue (mlirExpr);
1646
+ } else {
1647
+ // Since the update region includes more than one operation
1648
+ // we will resort to generating a cmpxchg loop.
1649
+ binop = llvm::AtomicRMWInst::BinOp::BAD_BINOP;
1643
1650
}
1644
- if (!isRegionArgUsed)
1645
- return opInst.emitError (" no atomic update operation with region argument"
1646
- " as operand found inside atomic.update region" );
1647
-
1648
- llvm::Value *llvmExpr = moduleTranslation.lookupValue (mlirExpr);
1649
- llvm::Value *llvmX = moduleTranslation.lookupValue (opInst.getX ());
1650
- llvm::Type *llvmXElementType = moduleTranslation.convertType (
1651
+ llvmX = moduleTranslation.lookupValue (opInst.getX ());
1652
+ llvmXElementType = moduleTranslation.convertType (
1651
1653
opInst.getRegion ().getArgument (0 ).getType ());
1652
1654
llvm::OpenMPIRBuilder::AtomicOpValue llvmAtomicX = {llvmX, llvmXElementType,
1653
1655
/* isSigned=*/ false ,
0 commit comments