mirror of https://github.com/llvm/circt.git
[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:
parent
96b54ebc67
commit
dd7b402d96
|
@ -1325,29 +1325,18 @@ struct PowUOpConversion : public OpConversionPattern<PowUOp> {
|
||||||
ConversionPatternRewriter &rewriter) const override {
|
ConversionPatternRewriter &rewriter) const override {
|
||||||
Type resultType = typeConverter->convertType(op.getResult().getType());
|
Type resultType = typeConverter->convertType(op.getResult().getType());
|
||||||
|
|
||||||
Location loc = op.getLoc();
|
Location loc = op->getLoc();
|
||||||
auto intType = cast<IntType>(op.getRhs().getType());
|
|
||||||
|
|
||||||
// transform a ** b into scf.for 0 to b step 1 { init *= a }, init = 1
|
Value zeroVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0));
|
||||||
Type integerType = rewriter.getIntegerType(intType.getWidth());
|
// zero extend both LHS & RHS to ensure the unsigned integers are
|
||||||
Value lowerBound = rewriter.create<hw::ConstantOp>(loc, integerType, 0);
|
// interpreted correctly when calculating power
|
||||||
Value upperBound =
|
auto lhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getLhs());
|
||||||
rewriter.create<ConversionOp>(loc, integerType, op.getRhs());
|
auto rhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getRhs());
|
||||||
Value step = rewriter.create<hw::ConstantOp>(loc, integerType, 1);
|
|
||||||
|
|
||||||
Value initVal = rewriter.create<hw::ConstantOp>(loc, resultType, 1);
|
// lower the exponentiation via MLIR's math dialect
|
||||||
Value lhsVal = rewriter.create<ConversionOp>(loc, resultType, op.getLhs());
|
auto pow = rewriter.create<mlir::math::IPowIOp>(loc, lhs, rhs);
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
|
rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, pow, 0);
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1111,9 +1111,11 @@ func.func @Conversions(%arg0: !moore.i16, %arg1: !moore.l16) {
|
||||||
|
|
||||||
// CHECK-LABEL: func.func @PowUOp
|
// CHECK-LABEL: func.func @PowUOp
|
||||||
func.func @PowUOp(%arg0: !moore.l32, %arg1: !moore.l32) {
|
func.func @PowUOp(%arg0: !moore.l32, %arg1: !moore.l32) {
|
||||||
// CHECK: %{{.*}} = scf.for %{{.*}} = %{{.*}} to %arg1 step %{{.*}} iter_args([[VAR:%.+]] = %{{.*}}) -> (i32) : i32 {
|
// CHECK: %[[ZEROVAL:.*]] = hw.constant false
|
||||||
// CHECK: [[MUL:%.+]] = comb.mul %arg0, [[VAR]] : i32
|
// CHECK: %[[CONCATA:.*]] = comb.concat %[[ZEROVAL]], %arg0 : i1, i32
|
||||||
// CHECK: scf.yield [[MUL]] : 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
|
%0 = moore.powu %arg0, %arg1 : l32
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue