-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][tosa] Fix tosa.Resize-to-linalg lowering #88514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Simplify the lowering of tosa.resize to linalg, to match more closely the implementation from the TOSA specification: some internal arithmetic operations are now performed on the integer types (rather than in floating point) to reduce the loss of precision and the num of generated operations. Signed-off-by: Fabrizio Indirli <[email protected]>
@llvm/pr-subscribers-mlir Author: None (fabrizio-indirli) ChangesSimplify the lowering of tosa.resize to linalg, to match more closely the implementation from the TOSA specification: some internal arithmetic operations are now performed on the integer types (rather than in floating point) to reduce the loss of precision and the num of generated operations. Full diff: https://github.com/llvm/llvm-project/pull/88514.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 7c477f2e1412be..1a743282adc487 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -1578,17 +1578,16 @@ class GenericResizeConverter : public OpRewritePattern<tosa::ResizeOp> {
}
// x = x * scale_d + offset;
// ix = floor(x / scale_n)
- // dx = x / scale_n - ix
- Value val = b.create<arith::UIToFPOp>(floatTy, in);
- scaleN = b.create<arith::UIToFPOp>(floatTy, scaleN);
- scaleD = b.create<arith::UIToFPOp>(floatTy, scaleD);
- offset = b.create<arith::SIToFPOp>(floatTy, offset);
- val = b.create<arith::MulFOp>(val, scaleD);
- val = b.create<arith::AddFOp>(val, offset);
- val = b.create<arith::DivFOp>(val, scaleN);
- index = b.create<math::FloorOp>(val);
- delta = b.create<arith::SubFOp>(val, index);
- index = b.create<arith::FPToSIOp>(b.getI32Type(), index);
+ Value val = b.create<arith::MulIOp>(in, scaleD);
+ val = b.create<arith::AddIOp>(val, offset);
+ index = b.create<arith::FloorDivSIOp>(val, scaleN);
+
+ // rx = x % scale_n
+ // dx = rx / scale_n
+ Value r = b.create<arith::RemSIOp>(val, scaleN);
+ Value rFp = b.create<arith::SIToFPOp>(floatTy, r);
+ Value scaleNfp = b.create<arith::UIToFPOp>(floatTy, scaleN);
+ delta = b.create<arith::DivFOp>(rFp, scaleNfp);
};
// Compute the ix and dx values for the X and Y dimensions - int case.
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
index 468e92e2a2661f..d42d0a46692d47 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
@@ -304,42 +304,36 @@ func.func @resize_nearest_fp32(%input: tensor<1x50x48x1xf32>) -> () {
// CHECK-DAG: %[[XMAX:.*]] = arith.constant 47
// CHECK: %[[Y:.+]] = arith.index_cast %[[IDX1]]
// CHECK: %[[X:.+]] = arith.index_cast %[[IDX2]]
- // CHECK-DAG: %[[ISCALE_Y_N:.*]] = arith.constant 64
- // CHECK-DAG: %[[ISCALE_Y_D:.*]] = arith.constant 2
- // CHECK-DAG: %[[ISCALE_X_N:.*]] = arith.constant 64
- // CHECK-DAG: %[[ISCALE_X_D:.*]] = arith.constant 2
- // CHECK-DAG: %[[IOFFSET_Y:.*]] = arith.constant -31
- // CHECK-DAG: %[[IOFFSET_X:.*]] = arith.constant -31
- // CHECK-DAG: %[[IBORDER_Y:.*]] = arith.constant 31
- // CHECK-DAG: %[[IBORDER_X:.*]] = arith.constant 31
-
- // CHECK: %[[Y0:.+]] = arith.uitofp %[[Y]]
- // CHECK: %[[SCALE_Y_N:.*]] = arith.uitofp %[[ISCALE_Y_N]]
- // CHECK: %[[SCALE_Y_D:.*]] = arith.uitofp %[[ISCALE_Y_D]]
- // CHECK: %[[OFFSET_Y:.*]] = arith.sitofp %[[IOFFSET_Y]]
- // CHECK: %[[VAL_29:.*]] = arith.mulf %[[Y0]], %[[SCALE_Y_D]]
- // CHECK: %[[VAL_31:.*]] = arith.addf %[[VAL_29]], %[[OFFSET_Y]]
- // CHECK: %[[VAL_33:.*]] = arith.divf %[[VAL_31]], %[[SCALE_Y_N]]
- // CHECK: %[[VAL_35:.*]] = math.floor %[[VAL_33]]
- // CHECK: %[[D_Y:.*]] = arith.subf %[[VAL_33]], %[[VAL_35]]
- // CHECK: %[[VAL_39:.*]] = arith.fptosi %[[VAL_35]]
-
- // CHECK: %[[X0:.+]] = arith.uitofp %[[X]]
- // CHECK: %[[SCALE_X_N:.*]] = arith.uitofp %[[ISCALE_X_N]]
- // CHECK: %[[SCALE_X_D:.*]] = arith.uitofp %[[ISCALE_X_D]]
- // CHECK: %[[OFFSET_X:.*]] = arith.sitofp %[[IOFFSET_X]]
- // CHECK: %[[VAL_30:.*]] = arith.mulf %[[X0]], %[[SCALE_X_D]]
- // CHECK: %[[VAL_32:.*]] = arith.addf %[[VAL_30]], %[[OFFSET_X]]
- // CHECK: %[[VAL_34:.*]] = arith.divf %[[VAL_32]], %[[SCALE_X_N]]
- // CHECK: %[[VAL_36:.*]] = math.floor %[[VAL_34]]
- // CHECK: %[[D_X:.*]] = arith.subf %[[VAL_34]], %[[VAL_36]]
- // CHECK: %[[VAL_40:.*]] = arith.fptosi %[[VAL_36]]
+ // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 64
+ // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 2
+ // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 64
+ // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 2
+ // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant -31
+ // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant -31
+ // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 31
+ // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 31
+
+ // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
+ // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
+ // CHECK: %[[IY_TEMP:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
+ // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
+ // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
+
+ // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
+ // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
+ // CHECK: %[[IX_TEMP:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
+ // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
+ // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
// CHECK-DAG: %[[ONE:.*]] = arith.constant 1
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
// CHECK: %[[PRED_Y:.*]] = arith.cmpf oge, %[[D_Y]], %[[HALF]]
// CHECK: %[[ROUND_Y:.*]] = arith.select %[[PRED_Y]], %[[ONE]], %[[ZERO]]
- // CHECK: %[[VAL_48:.*]] = arith.addi %[[VAL_39]], %[[ROUND_Y]]
+ // CHECK: %[[VAL_48:.*]] = arith.addi %[[IY_TEMP]], %[[ROUND_Y]]
// CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_48]]
// CHECK: %[[CLAMPED:.*]] = arith.minsi %[[YMAX]], %[[LOWER]]
// CHECK: %[[IDY:.*]] = arith.index_cast %[[CLAMPED]]
@@ -347,7 +341,7 @@ func.func @resize_nearest_fp32(%input: tensor<1x50x48x1xf32>) -> () {
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
// CHECK: %[[PRED_X:.*]] = arith.cmpf oge, %[[D_X]], %[[HALF]]
// CHECK: %[[ROUND_X:.*]] = arith.select %[[PRED_X]], %[[ONE]], %[[ZERO]]
- // CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_40]], %[[ROUND_X]]
+ // CHECK: %[[VAL_49:.*]] = arith.addi %[[IX_TEMP]], %[[ROUND_X]]
// CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_49]]
// CHECK: %[[CLAMPED:.*]] = arith.minsi %[[XMAX]], %[[LOWER]]
// CHECK: %[[IDX:.*]] = arith.index_cast %[[CLAMPED]]
@@ -374,36 +368,30 @@ func.func @resize_bilinear_fp(%input: tensor<1x23x24x1xf32>) -> () {
// CHECK-DAG: %[[X_MAX:.*]] = arith.constant 23
// CHECK: %[[Y:.+]] = arith.index_cast %[[IDX_1]]
// CHECK: %[[X:.+]] = arith.index_cast %[[IDX_2]]
- // CHECK-DAG: %[[ISCALE_Y_N:.*]] = arith.constant 4
- // CHECK-DAG: %[[ISCALE_Y_D:.*]] = arith.constant 1
- // CHECK-DAG: %[[ISCALE_X_N:.*]] = arith.constant 4
- // CHECK-DAG: %[[ISCALE_X_D:.*]] = arith.constant 1
- // CHECK-DAG: %[[IOFFSET_Y:.*]] = arith.constant 0
- // CHECK-DAG: %[[IOFFSET_X:.*]] = arith.constant 0
- // CHECK-DAG: %[[IBORDER_Y:.*]] = arith.constant 0
- // CHECK-DAG: %[[IBORDER_X:.*]] = arith.constant 0
-
- // CHECK: %[[Y0:.+]] = arith.uitofp %[[Y]]
- // CHECK: %[[SCALE_Y_N:.*]] = arith.uitofp %[[ISCALE_Y_N]]
- // CHECK: %[[SCALE_Y_D:.*]] = arith.uitofp %[[ISCALE_Y_D]]
- // CHECK: %[[OFFSET_Y:.*]] = arith.sitofp %[[IOFFSET_Y]]
- // CHECK: %[[VAL_29:.*]] = arith.mulf %[[Y0]], %[[SCALE_Y_D]]
- // CHECK: %[[VAL_31:.*]] = arith.addf %[[VAL_29]], %[[OFFSET_Y]]
- // CHECK: %[[VAL_33:.*]] = arith.divf %[[VAL_31]], %[[SCALE_Y_N]]
- // CHECK: %[[VAL_35:.*]] = math.floor %[[VAL_33]]
- // CHECK: %[[D_Y:.*]] = arith.subf %[[VAL_33]], %[[VAL_35]]
- // CHECK: %[[I_Y:.*]] = arith.fptosi %[[VAL_35]]
-
- // CHECK: %[[X0:.+]] = arith.uitofp %[[X]]
- // CHECK: %[[SCALE_X_N:.*]] = arith.uitofp %[[ISCALE_X_N]]
- // CHECK: %[[SCALE_X_D:.*]] = arith.uitofp %[[ISCALE_X_D]]
- // CHECK: %[[OFFSET_X:.*]] = arith.sitofp %[[IOFFSET_X]]
- // CHECK: %[[VAL_30:.*]] = arith.mulf %[[X0]], %[[SCALE_X_D]]
- // CHECK: %[[VAL_32:.*]] = arith.addf %[[VAL_30]], %[[OFFSET_X]]
- // CHECK: %[[VAL_34:.*]] = arith.divf %[[VAL_32]], %[[SCALE_X_N]]
- // CHECK: %[[VAL_36:.*]] = math.floor %[[VAL_34]]
- // CHECK: %[[D_X:.*]] = arith.subf %[[VAL_34]], %[[VAL_36]]
- // CHECK: %[[I_X:.*]] = arith.fptosi %[[VAL_36]]
+ // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 4
+ // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 1
+ // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 4
+ // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 1
+ // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant 0
+ // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant 0
+ // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 0
+ // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 0
+
+ // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
+ // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
+ // CHECK: %[[I_Y:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
+ // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
+ // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
+
+ // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
+ // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
+ // CHECK: %[[I_X:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
+ // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
+ // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
// Compute the left, right, and top indices for the bilinear interpolation.
|
@llvm/pr-subscribers-mlir-linalg Author: None (fabrizio-indirli) ChangesSimplify the lowering of tosa.resize to linalg, to match more closely the implementation from the TOSA specification: some internal arithmetic operations are now performed on the integer types (rather than in floating point) to reduce the loss of precision and the num of generated operations. Full diff: https://github.com/llvm/llvm-project/pull/88514.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 7c477f2e1412be..1a743282adc487 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -1578,17 +1578,16 @@ class GenericResizeConverter : public OpRewritePattern<tosa::ResizeOp> {
}
// x = x * scale_d + offset;
// ix = floor(x / scale_n)
- // dx = x / scale_n - ix
- Value val = b.create<arith::UIToFPOp>(floatTy, in);
- scaleN = b.create<arith::UIToFPOp>(floatTy, scaleN);
- scaleD = b.create<arith::UIToFPOp>(floatTy, scaleD);
- offset = b.create<arith::SIToFPOp>(floatTy, offset);
- val = b.create<arith::MulFOp>(val, scaleD);
- val = b.create<arith::AddFOp>(val, offset);
- val = b.create<arith::DivFOp>(val, scaleN);
- index = b.create<math::FloorOp>(val);
- delta = b.create<arith::SubFOp>(val, index);
- index = b.create<arith::FPToSIOp>(b.getI32Type(), index);
+ Value val = b.create<arith::MulIOp>(in, scaleD);
+ val = b.create<arith::AddIOp>(val, offset);
+ index = b.create<arith::FloorDivSIOp>(val, scaleN);
+
+ // rx = x % scale_n
+ // dx = rx / scale_n
+ Value r = b.create<arith::RemSIOp>(val, scaleN);
+ Value rFp = b.create<arith::SIToFPOp>(floatTy, r);
+ Value scaleNfp = b.create<arith::UIToFPOp>(floatTy, scaleN);
+ delta = b.create<arith::DivFOp>(rFp, scaleNfp);
};
// Compute the ix and dx values for the X and Y dimensions - int case.
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
index 468e92e2a2661f..d42d0a46692d47 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir
@@ -304,42 +304,36 @@ func.func @resize_nearest_fp32(%input: tensor<1x50x48x1xf32>) -> () {
// CHECK-DAG: %[[XMAX:.*]] = arith.constant 47
// CHECK: %[[Y:.+]] = arith.index_cast %[[IDX1]]
// CHECK: %[[X:.+]] = arith.index_cast %[[IDX2]]
- // CHECK-DAG: %[[ISCALE_Y_N:.*]] = arith.constant 64
- // CHECK-DAG: %[[ISCALE_Y_D:.*]] = arith.constant 2
- // CHECK-DAG: %[[ISCALE_X_N:.*]] = arith.constant 64
- // CHECK-DAG: %[[ISCALE_X_D:.*]] = arith.constant 2
- // CHECK-DAG: %[[IOFFSET_Y:.*]] = arith.constant -31
- // CHECK-DAG: %[[IOFFSET_X:.*]] = arith.constant -31
- // CHECK-DAG: %[[IBORDER_Y:.*]] = arith.constant 31
- // CHECK-DAG: %[[IBORDER_X:.*]] = arith.constant 31
-
- // CHECK: %[[Y0:.+]] = arith.uitofp %[[Y]]
- // CHECK: %[[SCALE_Y_N:.*]] = arith.uitofp %[[ISCALE_Y_N]]
- // CHECK: %[[SCALE_Y_D:.*]] = arith.uitofp %[[ISCALE_Y_D]]
- // CHECK: %[[OFFSET_Y:.*]] = arith.sitofp %[[IOFFSET_Y]]
- // CHECK: %[[VAL_29:.*]] = arith.mulf %[[Y0]], %[[SCALE_Y_D]]
- // CHECK: %[[VAL_31:.*]] = arith.addf %[[VAL_29]], %[[OFFSET_Y]]
- // CHECK: %[[VAL_33:.*]] = arith.divf %[[VAL_31]], %[[SCALE_Y_N]]
- // CHECK: %[[VAL_35:.*]] = math.floor %[[VAL_33]]
- // CHECK: %[[D_Y:.*]] = arith.subf %[[VAL_33]], %[[VAL_35]]
- // CHECK: %[[VAL_39:.*]] = arith.fptosi %[[VAL_35]]
-
- // CHECK: %[[X0:.+]] = arith.uitofp %[[X]]
- // CHECK: %[[SCALE_X_N:.*]] = arith.uitofp %[[ISCALE_X_N]]
- // CHECK: %[[SCALE_X_D:.*]] = arith.uitofp %[[ISCALE_X_D]]
- // CHECK: %[[OFFSET_X:.*]] = arith.sitofp %[[IOFFSET_X]]
- // CHECK: %[[VAL_30:.*]] = arith.mulf %[[X0]], %[[SCALE_X_D]]
- // CHECK: %[[VAL_32:.*]] = arith.addf %[[VAL_30]], %[[OFFSET_X]]
- // CHECK: %[[VAL_34:.*]] = arith.divf %[[VAL_32]], %[[SCALE_X_N]]
- // CHECK: %[[VAL_36:.*]] = math.floor %[[VAL_34]]
- // CHECK: %[[D_X:.*]] = arith.subf %[[VAL_34]], %[[VAL_36]]
- // CHECK: %[[VAL_40:.*]] = arith.fptosi %[[VAL_36]]
+ // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 64
+ // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 2
+ // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 64
+ // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 2
+ // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant -31
+ // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant -31
+ // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 31
+ // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 31
+
+ // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
+ // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
+ // CHECK: %[[IY_TEMP:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
+ // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
+ // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
+
+ // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
+ // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
+ // CHECK: %[[IX_TEMP:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
+ // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
+ // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
// CHECK-DAG: %[[ONE:.*]] = arith.constant 1
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
// CHECK: %[[PRED_Y:.*]] = arith.cmpf oge, %[[D_Y]], %[[HALF]]
// CHECK: %[[ROUND_Y:.*]] = arith.select %[[PRED_Y]], %[[ONE]], %[[ZERO]]
- // CHECK: %[[VAL_48:.*]] = arith.addi %[[VAL_39]], %[[ROUND_Y]]
+ // CHECK: %[[VAL_48:.*]] = arith.addi %[[IY_TEMP]], %[[ROUND_Y]]
// CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_48]]
// CHECK: %[[CLAMPED:.*]] = arith.minsi %[[YMAX]], %[[LOWER]]
// CHECK: %[[IDY:.*]] = arith.index_cast %[[CLAMPED]]
@@ -347,7 +341,7 @@ func.func @resize_nearest_fp32(%input: tensor<1x50x48x1xf32>) -> () {
// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
// CHECK: %[[PRED_X:.*]] = arith.cmpf oge, %[[D_X]], %[[HALF]]
// CHECK: %[[ROUND_X:.*]] = arith.select %[[PRED_X]], %[[ONE]], %[[ZERO]]
- // CHECK: %[[VAL_49:.*]] = arith.addi %[[VAL_40]], %[[ROUND_X]]
+ // CHECK: %[[VAL_49:.*]] = arith.addi %[[IX_TEMP]], %[[ROUND_X]]
// CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_49]]
// CHECK: %[[CLAMPED:.*]] = arith.minsi %[[XMAX]], %[[LOWER]]
// CHECK: %[[IDX:.*]] = arith.index_cast %[[CLAMPED]]
@@ -374,36 +368,30 @@ func.func @resize_bilinear_fp(%input: tensor<1x23x24x1xf32>) -> () {
// CHECK-DAG: %[[X_MAX:.*]] = arith.constant 23
// CHECK: %[[Y:.+]] = arith.index_cast %[[IDX_1]]
// CHECK: %[[X:.+]] = arith.index_cast %[[IDX_2]]
- // CHECK-DAG: %[[ISCALE_Y_N:.*]] = arith.constant 4
- // CHECK-DAG: %[[ISCALE_Y_D:.*]] = arith.constant 1
- // CHECK-DAG: %[[ISCALE_X_N:.*]] = arith.constant 4
- // CHECK-DAG: %[[ISCALE_X_D:.*]] = arith.constant 1
- // CHECK-DAG: %[[IOFFSET_Y:.*]] = arith.constant 0
- // CHECK-DAG: %[[IOFFSET_X:.*]] = arith.constant 0
- // CHECK-DAG: %[[IBORDER_Y:.*]] = arith.constant 0
- // CHECK-DAG: %[[IBORDER_X:.*]] = arith.constant 0
-
- // CHECK: %[[Y0:.+]] = arith.uitofp %[[Y]]
- // CHECK: %[[SCALE_Y_N:.*]] = arith.uitofp %[[ISCALE_Y_N]]
- // CHECK: %[[SCALE_Y_D:.*]] = arith.uitofp %[[ISCALE_Y_D]]
- // CHECK: %[[OFFSET_Y:.*]] = arith.sitofp %[[IOFFSET_Y]]
- // CHECK: %[[VAL_29:.*]] = arith.mulf %[[Y0]], %[[SCALE_Y_D]]
- // CHECK: %[[VAL_31:.*]] = arith.addf %[[VAL_29]], %[[OFFSET_Y]]
- // CHECK: %[[VAL_33:.*]] = arith.divf %[[VAL_31]], %[[SCALE_Y_N]]
- // CHECK: %[[VAL_35:.*]] = math.floor %[[VAL_33]]
- // CHECK: %[[D_Y:.*]] = arith.subf %[[VAL_33]], %[[VAL_35]]
- // CHECK: %[[I_Y:.*]] = arith.fptosi %[[VAL_35]]
-
- // CHECK: %[[X0:.+]] = arith.uitofp %[[X]]
- // CHECK: %[[SCALE_X_N:.*]] = arith.uitofp %[[ISCALE_X_N]]
- // CHECK: %[[SCALE_X_D:.*]] = arith.uitofp %[[ISCALE_X_D]]
- // CHECK: %[[OFFSET_X:.*]] = arith.sitofp %[[IOFFSET_X]]
- // CHECK: %[[VAL_30:.*]] = arith.mulf %[[X0]], %[[SCALE_X_D]]
- // CHECK: %[[VAL_32:.*]] = arith.addf %[[VAL_30]], %[[OFFSET_X]]
- // CHECK: %[[VAL_34:.*]] = arith.divf %[[VAL_32]], %[[SCALE_X_N]]
- // CHECK: %[[VAL_36:.*]] = math.floor %[[VAL_34]]
- // CHECK: %[[D_X:.*]] = arith.subf %[[VAL_34]], %[[VAL_36]]
- // CHECK: %[[I_X:.*]] = arith.fptosi %[[VAL_36]]
+ // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 4
+ // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 1
+ // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 4
+ // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 1
+ // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant 0
+ // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant 0
+ // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 0
+ // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 0
+
+ // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
+ // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
+ // CHECK: %[[I_Y:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
+ // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
+ // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
+ // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
+
+ // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
+ // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
+ // CHECK: %[[I_X:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
+ // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
+ // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
+ // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
// Compute the left, right, and top indices for the bilinear interpolation.
|
@rsuderman @GeorgeARM @Hsiangkai |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Aligned with the spec. Leaving to @kuhar @rsuderman
Simplify the lowering of tosa.resize to linalg, to match more closely the implementation from the TOSA specification: some internal arithmetic operations are now performed on the integer types (rather than in floating point) to reduce the loss of precision and the num of generated operations.