[mlir][emitc] Lower arith.divui, remui (#99313)

This commit lowers `arith.divui` and `arith.remui` to EmitC by wrapping
those operations with type conversions.
This commit is contained in:
Corentin Ferry 2024-07-31 10:41:18 +02:00 committed by GitHub
parent 79996cd0c2
commit 36b2c22e07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 0 deletions

View File

@ -421,6 +421,38 @@ public:
}
};
template <class ArithOp, class EmitCOp>
class BinaryUIOpConversion final : public OpConversionPattern<ArithOp> {
public:
using OpConversionPattern<ArithOp>::OpConversionPattern;
LogicalResult
matchAndRewrite(ArithOp uiBinOp, typename ArithOp::Adaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
Type newRetTy = this->getTypeConverter()->convertType(uiBinOp.getType());
if (!newRetTy)
return rewriter.notifyMatchFailure(uiBinOp,
"converting result type failed");
if (!isa<IntegerType>(newRetTy)) {
return rewriter.notifyMatchFailure(uiBinOp, "expected integer type");
}
Type unsignedType =
adaptIntegralTypeSignedness(newRetTy, /*needsUnsigned=*/true);
if (!unsignedType)
return rewriter.notifyMatchFailure(uiBinOp,
"converting result type failed");
Value lhsAdapted = adaptValueType(uiBinOp.getLhs(), rewriter, unsignedType);
Value rhsAdapted = adaptValueType(uiBinOp.getRhs(), rewriter, unsignedType);
auto newDivOp =
rewriter.create<EmitCOp>(uiBinOp.getLoc(), unsignedType,
ArrayRef<Value>{lhsAdapted, rhsAdapted});
Value resultAdapted = adaptValueType(newDivOp, rewriter, newRetTy);
rewriter.replaceOp(uiBinOp, resultAdapted);
return success();
}
};
template <typename ArithOp, typename EmitCOp>
class IntegerOpConversion final : public OpConversionPattern<ArithOp> {
public:
@ -722,6 +754,8 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
ArithOpConversion<arith::MulFOp, emitc::MulOp>,
ArithOpConversion<arith::RemSIOp, emitc::RemOp>,
ArithOpConversion<arith::SubFOp, emitc::SubOp>,
BinaryUIOpConversion<arith::DivUIOp, emitc::DivOp>,
BinaryUIOpConversion<arith::RemUIOp, emitc::RemOp>,
IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
IntegerOpConversion<arith::SubIOp, emitc::SubOp>,

View File

@ -134,3 +134,19 @@ func.func @arith_shrui_i1(%arg0: i1, %arg1: i1) {
%shrui = arith.shrui %arg0, %arg1 : i1
return
}
// -----
func.func @arith_divui_vector(%arg0: vector<5xi32>, %arg1: vector<5xi32>) -> vector<5xi32> {
// expected-error @+1 {{failed to legalize operation 'arith.divui'}}
%divui = arith.divui %arg0, %arg1 : vector<5xi32>
return %divui: vector<5xi32>
}
// -----
func.func @arith_remui_vector(%arg0: vector<5xi32>, %arg1: vector<5xi32>) -> vector<5xi32> {
// expected-error @+1 {{failed to legalize operation 'arith.remui'}}
%divui = arith.remui %arg0, %arg1 : vector<5xi32>
return %divui: vector<5xi32>
}

View File

@ -717,3 +717,21 @@ func.func @arith_index_castui(%arg0: i32) -> i32 {
return %int : i32
}
// -----
func.func @arith_divui_remui(%arg0: i32, %arg1: i32) -> i32 {
// CHECK-LABEL: arith_divui_remui
// CHECK-SAME: (%[[Arg0:[^ ]*]]: i32, %[[Arg1:[^ ]*]]: i32)
// CHECK: %[[Conv0:.*]] = emitc.cast %[[Arg0]] : i32 to ui32
// CHECK: %[[Conv1:.*]] = emitc.cast %[[Arg1]] : i32 to ui32
// CHECK: %[[Div:.*]] = emitc.div %[[Conv0]], %[[Conv1]] : (ui32, ui32) -> ui32
%div = arith.divui %arg0, %arg1 : i32
// CHECK: %[[Conv2:.*]] = emitc.cast %[[Arg0]] : i32 to ui32
// CHECK: %[[Conv3:.*]] = emitc.cast %[[Arg1]] : i32 to ui32
// CHECK: %[[Rem:.*]] = emitc.rem %[[Conv2]], %[[Conv3]] : (ui32, ui32) -> ui32
%rem = arith.remui %arg0, %arg1 : i32
return %div : i32
}