Skip to content

Commit 36b2c22

Browse files
authored
[mlir][emitc] Lower arith.divui, remui (llvm#99313)
This commit lowers `arith.divui` and `arith.remui` to EmitC by wrapping those operations with type conversions.
1 parent 79996cd commit 36b2c22

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,38 @@ class ArithOpConversion final : public OpConversionPattern<ArithOp> {
421421
}
422422
};
423423

424+
template <class ArithOp, class EmitCOp>
425+
class BinaryUIOpConversion final : public OpConversionPattern<ArithOp> {
426+
public:
427+
using OpConversionPattern<ArithOp>::OpConversionPattern;
428+
429+
LogicalResult
430+
matchAndRewrite(ArithOp uiBinOp, typename ArithOp::Adaptor adaptor,
431+
ConversionPatternRewriter &rewriter) const override {
432+
Type newRetTy = this->getTypeConverter()->convertType(uiBinOp.getType());
433+
if (!newRetTy)
434+
return rewriter.notifyMatchFailure(uiBinOp,
435+
"converting result type failed");
436+
if (!isa<IntegerType>(newRetTy)) {
437+
return rewriter.notifyMatchFailure(uiBinOp, "expected integer type");
438+
}
439+
Type unsignedType =
440+
adaptIntegralTypeSignedness(newRetTy, /*needsUnsigned=*/true);
441+
if (!unsignedType)
442+
return rewriter.notifyMatchFailure(uiBinOp,
443+
"converting result type failed");
444+
Value lhsAdapted = adaptValueType(uiBinOp.getLhs(), rewriter, unsignedType);
445+
Value rhsAdapted = adaptValueType(uiBinOp.getRhs(), rewriter, unsignedType);
446+
447+
auto newDivOp =
448+
rewriter.create<EmitCOp>(uiBinOp.getLoc(), unsignedType,
449+
ArrayRef<Value>{lhsAdapted, rhsAdapted});
450+
Value resultAdapted = adaptValueType(newDivOp, rewriter, newRetTy);
451+
rewriter.replaceOp(uiBinOp, resultAdapted);
452+
return success();
453+
}
454+
};
455+
424456
template <typename ArithOp, typename EmitCOp>
425457
class IntegerOpConversion final : public OpConversionPattern<ArithOp> {
426458
public:
@@ -722,6 +754,8 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
722754
ArithOpConversion<arith::MulFOp, emitc::MulOp>,
723755
ArithOpConversion<arith::RemSIOp, emitc::RemOp>,
724756
ArithOpConversion<arith::SubFOp, emitc::SubOp>,
757+
BinaryUIOpConversion<arith::DivUIOp, emitc::DivOp>,
758+
BinaryUIOpConversion<arith::RemUIOp, emitc::RemOp>,
725759
IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
726760
IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
727761
IntegerOpConversion<arith::SubIOp, emitc::SubOp>,

mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,19 @@ func.func @arith_shrui_i1(%arg0: i1, %arg1: i1) {
134134
%shrui = arith.shrui %arg0, %arg1 : i1
135135
return
136136
}
137+
138+
// -----
139+
140+
func.func @arith_divui_vector(%arg0: vector<5xi32>, %arg1: vector<5xi32>) -> vector<5xi32> {
141+
// expected-error @+1 {{failed to legalize operation 'arith.divui'}}
142+
%divui = arith.divui %arg0, %arg1 : vector<5xi32>
143+
return %divui: vector<5xi32>
144+
}
145+
146+
// -----
147+
148+
func.func @arith_remui_vector(%arg0: vector<5xi32>, %arg1: vector<5xi32>) -> vector<5xi32> {
149+
// expected-error @+1 {{failed to legalize operation 'arith.remui'}}
150+
%divui = arith.remui %arg0, %arg1 : vector<5xi32>
151+
return %divui: vector<5xi32>
152+
}

mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,3 +717,21 @@ func.func @arith_index_castui(%arg0: i32) -> i32 {
717717

718718
return %int : i32
719719
}
720+
721+
// -----
722+
723+
func.func @arith_divui_remui(%arg0: i32, %arg1: i32) -> i32 {
724+
// CHECK-LABEL: arith_divui_remui
725+
// CHECK-SAME: (%[[Arg0:[^ ]*]]: i32, %[[Arg1:[^ ]*]]: i32)
726+
// CHECK: %[[Conv0:.*]] = emitc.cast %[[Arg0]] : i32 to ui32
727+
// CHECK: %[[Conv1:.*]] = emitc.cast %[[Arg1]] : i32 to ui32
728+
// CHECK: %[[Div:.*]] = emitc.div %[[Conv0]], %[[Conv1]] : (ui32, ui32) -> ui32
729+
%div = arith.divui %arg0, %arg1 : i32
730+
731+
// CHECK: %[[Conv2:.*]] = emitc.cast %[[Arg0]] : i32 to ui32
732+
// CHECK: %[[Conv3:.*]] = emitc.cast %[[Arg1]] : i32 to ui32
733+
// CHECK: %[[Rem:.*]] = emitc.rem %[[Conv2]], %[[Conv3]] : (ui32, ui32) -> ui32
734+
%rem = arith.remui %arg0, %arg1 : i32
735+
736+
return %div : i32
737+
}

0 commit comments

Comments
 (0)