Repository: PaddlePaddle/Paddle
Pull request #71645: [CINN] Add simplify for `-Mul(S0, -1) => S0`
Author: login: ooooo-create
Created: 2025-03-13T13:15:52Z | Merged: 2025-03-15T11:28:50Z

<!-- TemplateReference: https://github.com/PaddlePaddle/Paddle/wiki/PULL-REQUEST-TEMPLATE--REFERENCE -->
<!-- Demo: https://github.com/PaddlePaddle/Paddle/pull/24810 -->

### PR Category
<!-- One of [ User Experience | Execute Infrastructure | Operator Mechanism | CINN | Custom Device | Performance Optimization | Distributed Strategy | Parameter Server | Communication Library | Auto Parallel | Inference | Environment Adaptation ] -->
CINN

### PR Types
<!-- One of [ New features | Bug fixes | Improvements | Performance | BC Breaking | Deprecations | Docs | Devs | Not User Facing | Security | Deprecations | Others ] -->
Others

### Description
<!-- Describe what you’ve done -->
Pcard-67164
- Add simplify for `-Mul(S0, -1) => S0`
- Add simplify for `-Div(S0, -1) => S0`


Diff:
diff --git a/paddle/pir/src/dialect/shape/utils/dim_expr_util.cc b/paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
index 1d05cc41e06246..d3d271ec280f50 100644
--- a/paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
+++ b/paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
@@ -88,6 +88,43 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      int minus_one_nums = 0;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&minus_one_nums](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              minus_one_nums++;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (minus_one_nums > 0) {
+        PADDLE_ENFORCE_EQ(minus_one_nums,
+                          1,
+                          common::errors::InvalidArgument(
+                              "The number of -1 in the operands "
+                              "of Mul should be 1, but got %d , "
+                              "please check the simplify logic for Mul.",
+                              minus_one_nums));
+      } else {
+        return expr;
+      }
+      if (mut_operands.size() == 1) {
+        return mut_operands.at(0);
+      } else {
+        return Mul<DimExpr>{List<DimExpr>{mut_operands}};
+      }
+    } else if (inner_expr.Has<Div<DimExpr>>()) {
+      const auto& rhs = inner_expr.Get<Div<DimExpr>>()->rhs;
+      if (rhs.Has<std::int64_t>() && rhs.Get<std::int64_t>() == -1) {
+        return inner_expr.Get<Div<DimExpr>>()->lhs;
+      }
+      return expr;
     } else {
       return expr;
     }
diff --git a/test/cpp/pir/shape_dialect/simplify_dim_expr_test.cc b/test/cpp/pir/shape_dialect/simplify_dim_expr_test.cc
index d477f25b5bb033..6f3ffa1ab52662 100644
--- a/test/cpp/pir/shape_dialect/simplify_dim_expr_test.cc
+++ b/test/cpp/pir/shape_dialect/simplify_dim_expr_test.cc
@@ -210,6 +210,21 @@ TEST(Simplify, FoldRedundantBroadcast) {
   ASSERT_TRUE((simplify_bc == Broadcast<DimExpr>{{S0, S1}}));
 }
 
+TEST(Simplify, SimplifyDoubleNegForMulAndDiv) {
+  // Negative(Mul(S0, Negative(1))) => S0
+  DimExpr S0{"S0"};
+  DimExpr mul{Mul<DimExpr>{{S0, Negative<DimExpr>{DimExpr(1)}}}};
+  DimExpr neg_mul{Negative<DimExpr>{mul}};
+  DimExpr simplify_neg_mul = SimplifyDimExpr(neg_mul);
+  ASSERT_TRUE((simplify_neg_mul == S0));
+
+  // Negative(Div(S0, Negative(1))) => S0
+  DimExpr div{Div<DimExpr>{S0, Negative<DimExpr>{DimExpr(1)}}};
+  DimExpr neg_div{Negative<DimExpr>{div}};
+  DimExpr simplify_neg_div = SimplifyDimExpr(neg_div);
+  ASSERT_TRUE((simplify_neg_div == S0));
+}
+
 TEST(Simplify, Case1) {
   // Div(Mul(Div(Mul(Broadcast(S11, S8), Broadcast(S10, S13, S4, S7),
   // Broadcast(S12, S3, S6, S9)), S0)), 16), 49)


Reviews:
user: login: zyfncg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T03:16:45Z
user: login: ooooo-create
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T03:31:26Z
user: login: zyfncg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T03:41:32Z
user: login: gongshaotian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T04:01:17Z
user: login: ooooo-create
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T09:21:36Z
user: login: zyfncg
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T11:28:44Z

Review comments:
diff_hunk: @@ -88,6 +88,35 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      bool has_minus_one = false;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&has_minus_one](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              has_minus_one = true;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (!has_minus_one) {
+        return expr;
+      }
path: paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
user: login: zyfncg
body: 是否需要考虑 -1 的数量？
created_at: 2025-03-14T03:11:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,6 +88,35 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      bool has_minus_one = false;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&has_minus_one](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              has_minus_one = true;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (!has_minus_one) {
+        return expr;
+      }
path: paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
user: login: ooooo-create
body: 之前想加这个判断的，但是在进行这个化简之前，有一个 SimplifyOneOperand 化简，会把 mul 给化简，mul 化简完应该只有一个整数
created_at: 2025-03-14T03:31:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,6 +88,35 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      bool has_minus_one = false;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&has_minus_one](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              has_minus_one = true;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (!has_minus_one) {
+        return expr;
+      }
path: paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
user: login: zyfncg
body: 稳妥起见这里最好处理的完备些，多些冗余设计总比突然出现没考虑到的情况好
created_at: 2025-03-14T03:41:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,6 +88,35 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      bool has_minus_one = false;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&has_minus_one](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              has_minus_one = true;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (!has_minus_one) {
+        return expr;
+      }
path: paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
user: login: gongshaotian
body: mul化简时会把能化简的静态dim合并起来
created_at: 2025-03-14T04:01:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,6 +88,35 @@ struct SimplifyDoubleNeg {
       return ret_expr;
     } else if (inner_expr.Has<std::int64_t>()) {
       return -inner_expr.Get<std::int64_t>();
+    } else if (inner_expr.Has<Mul<DimExpr>>()) {
+      std::vector<DimExpr> mut_operands =
+          *inner_expr.Get<Mul<DimExpr>>().operands;
+      bool has_minus_one = false;
+      auto it = std::remove_if(
+          mut_operands.begin(),
+          mut_operands.end(),
+          [&has_minus_one](DimExpr x) {
+            if (x.Has<std::int64_t>() && x.Get<std::int64_t>() == -1) {
+              has_minus_one = true;
+              return true;
+            }
+            return false;
+          });
+      mut_operands.erase(it, mut_operands.end());
+      if (!has_minus_one) {
+        return expr;
+      }
path: paddle/pir/src/dialect/shape/utils/dim_expr_util.cc
user: login: ooooo-create
body: 现在是当存在 -1 时，加了个断言检查数量为1，不然就表示 Mul 的化简有问题，如果有问题，这样也能比较好的定位问题吧，这样子可以不
created_at: 2025-03-14T09:21:36Z
author_association: CONTRIBUTOR

PR comments:
user: login: paddle-bot[bot]
created_at: 2025-03-13T13:15:58Z
body: 你的PR提交成功，感谢你对开源项目的贡献!
请关注后续CI自动化测试结果，详情请参考[Paddle-CI手册](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/dev_guides/git_guides/paddle_ci_manual_cn.html)。
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See [Paddle CI Manual](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/dev_guides/git_guides/paddle_ci_manual_cn.html) for details.
author_association: NONE
user: login: gongshaotian
created_at: 2025-03-14T02:59:38Z
body: 标题写错啦，max -> mul
author_association: CONTRIBUTOR