[MooreToCore] Lower moore.powu to math.ipowi (#8654)

Change PowUOpConversion to call into the MLIR math dialect for unsigned 
integer exponentiation.
This commit is contained in:
Liam Jay 2025-07-11 06:50:42 +09:00 committed by GitHub
parent 96b54ebc67
commit dd7b402d96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 23 deletions

View File

@ -1325,29 +1325,18 @@ struct PowUOpConversion : public OpConversionPattern<PowUOp> {
ConversionPatternRewriter &rewriter) const override {
Type resultType = typeConverter->convertType(op.getResult().getType());
Location loc = op.getLoc();
auto intType = cast<IntType>(op.getRhs().getType());
Location loc = op->getLoc();
// transform a ** b into scf.for 0 to b step 1 { init *= a }, init = 1
Type integerType = rewriter.getIntegerType(intType.getWidth());
Value lowerBound = rewriter.create<hw::ConstantOp>(loc, integerType, 0);
Value upperBound =
rewriter.create<ConversionOp>(loc, integerType, op.getRhs());
Value step = rewriter.create<hw::ConstantOp>(loc, integerType, 1);
Value zeroVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0));
// zero extend both LHS & RHS to ensure the unsigned integers are
// interpreted correctly when calculating power
auto lhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getLhs());
auto rhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getRhs());
Value initVal = rewriter.create<hw::ConstantOp>(loc, resultType, 1);
Value lhsVal = rewriter.create<ConversionOp>(loc, resultType, op.getLhs());
auto forOp = rewriter.create<scf::ForOp>(
loc, lowerBound, upperBound, step, ValueRange(initVal),
[&](OpBuilder &builder, Location loc, Value i, ValueRange iterArgs) {
Value loopVar = iterArgs.front();
Value mul = rewriter.create<comb::MulOp>(loc, lhsVal, loopVar);
rewriter.create<scf::YieldOp>(loc, ValueRange(mul));
});
rewriter.replaceOp(op, forOp.getResult(0));
// lower the exponentiation via MLIR's math dialect
auto pow = rewriter.create<mlir::math::IPowIOp>(loc, lhs, rhs);
rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, pow, 0);
return success();
}
};

View File

@ -1111,9 +1111,11 @@ func.func @Conversions(%arg0: !moore.i16, %arg1: !moore.l16) {
// CHECK-LABEL: func.func @PowUOp
func.func @PowUOp(%arg0: !moore.l32, %arg1: !moore.l32) {
// CHECK: %{{.*}} = scf.for %{{.*}} = %{{.*}} to %arg1 step %{{.*}} iter_args([[VAR:%.+]] = %{{.*}}) -> (i32) : i32 {
// CHECK: [[MUL:%.+]] = comb.mul %arg0, [[VAR]] : i32
// CHECK: scf.yield [[MUL]] : i32
// CHECK: %[[ZEROVAL:.*]] = hw.constant false
// CHECK: %[[CONCATA:.*]] = comb.concat %[[ZEROVAL]], %arg0 : i1, i32
// CHECK: %[[CONCATB:.*]] = comb.concat %[[ZEROVAL]], %arg1 : i1, i32
// CHECK: %[[RES:.*]] = math.ipowi %[[CONCATA]], %[[CONCATB]] : i33
// CHECK: comb.extract %[[RES]] from 0 : (i33) -> i32
%0 = moore.powu %arg0, %arg1 : l32
return
}