return {};
}
+OpFoldResult ReverseOp::fold(ArrayRef<Attribute> operands) {
+ auto operand = getInput();
+ auto operandTy = operand.getType().cast<ShapedType>();
+ auto axis = getAxis();
+ auto operandAttr = operands[0].dyn_cast_or_null<SplatElementsAttr>();
+ if (operandAttr)
+ return operandAttr;
+
+ // If the dim-length is 1, tosa.reverse is a no-op.
+ if (operandTy.hasRank() && operandTy.getDimSize(axis) == 1)
+ return operand;
+
+ return {};
+}
+
OpFoldResult SliceOp::fold(ArrayRef<Attribute> operands) {
auto inputTy = getInput().getType().dyn_cast<RankedTensorType>();
auto outputTy = getType().dyn_cast<RankedTensorType>();
// CHECK: return %[[SPLAT]]
return %cast : tensor<i32>
}
+
+// -----
+
+// CHECK-LABEL: @reverse_splat
+func.func @reverse_splat() -> tensor<10xi32> {
+ // CHECK: %[[SPLAT:.+]] = "tosa.const"() {value = dense<42> : tensor<10xi32>}
+ %splat = "tosa.const"() {value = dense<42> : tensor<10xi32>} : () -> tensor<10xi32>
+ %reverse = "tosa.reverse"(%splat) { axis = 0 : i64 } : (tensor<10xi32>) -> tensor<10xi32>
+ // CHECK: return %[[SPLAT]]
+ return %reverse : tensor<10xi32>
+}
+
+// -----
+
+// CHECK-LABEL: @reverse_length_one
+func.func @reverse_length_one(%arg0 : tensor<10x1xi32>) -> (tensor<10x1xi32>, tensor<10x1xi32>) {
+ %nofold = "tosa.reverse"(%arg0) { axis = 0 : i64 } : (tensor<10x1xi32>) -> tensor<10x1xi32>
+ %fold = "tosa.reverse"(%arg0) { axis = 1 : i64 } : (tensor<10x1xi32>) -> tensor<10x1xi32>
+ // CHECK: %[[NOFOLD:.+]] = "tosa.reverse"(%arg0) {axis = 0 : i64}
+ // CHECK: return %[[NOFOLD]], %arg0
+ return %nofold, %fold : tensor<10x1xi32>, tensor<10x1xi32>
+}