[PATCH] D73728: [SCEV] SCEVExpander::isHighCostExpansionHelper(): cost-model add/mul

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 30 10:41:00 PST 2020


lebedev.ri created this revision.
lebedev.ri added reviewers: reames, mkazantsev, wmi, sanjoy.
lebedev.ri added a project: LLVM.
Herald added a subscriber: hiraditya.
lebedev.ri added a parent revision: D73722: [SCEV] SCEVExpander::isHighCostExpansionHelper(): cost-model plain UDiv.

While this resolves the regression from D73722 <https://reviews.llvm.org/D73722> in `llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll`,
this now regresses `llvm/test/Transforms/IndVarSimplify/elim-extend.ll` `@nestedIV` test,
we no longer can perform that expansion within default budget of `4`, but require budget of `6`.

Since that does not result in any other instructions being deleted,
i suspect this is a "true" regression, which might indicate that
either we don't reuse existing instructions/expressions hard enough,
or this is an unfortunate ordering - perhaps we later expand
some other IV, that shares the subexpressions and thus cost.
I'm not sure how to smartly deal with that.

That being said, the basic idea here is simple.

  Op0,  Op1, Op2 ...
   |     |    |
   \--+--/    |
      |       |
      \---+---/   

I.e. given N operands, we will have N-1 operations,
so we have to add cost of an add (mul) for **every** Op processed,
**except** the first one, plus we need to recurse into *every* Op.

I'm guessing there's already canonicalization that ensures we won't
have `1` operand in `scMulExpr`, and no `0` in `scAddExpr`/`scMulExpr`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73728

Files:
  llvm/lib/Analysis/ScalarEvolutionExpander.cpp
  llvm/test/Transforms/IndVarSimplify/elim-extend.ll
  llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll


Index: llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll
+++ llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll
@@ -19,9 +19,6 @@
 ; CHECK-NEXT:    [[CMP8:%.*]] = icmp ugt i32 [[LEN:%.*]], 11
 ; CHECK-NEXT:    br i1 [[CMP8]], label [[WHILE_BODY_LR_PH:%.*]], label [[WHILE_END:%.*]]
 ; CHECK:       while.body.lr.ph:
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], -12
-; CHECK-NEXT:    [[TMP1:%.*]] = udiv i32 [[TMP0]], 12
-; CHECK-NEXT:    [[TMP2:%.*]] = mul i32 [[TMP1]], 12
 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
 ; CHECK:       while.body:
 ; CHECK-NEXT:    [[KEYLEN_010:%.*]] = phi i32 [ [[LEN]], [[WHILE_BODY_LR_PH]] ], [ [[SUB:%.*]], [[WHILE_BODY]] ]
@@ -39,10 +36,10 @@
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[SUB]], 11
 ; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_COND_WHILE_END_CRIT_EDGE:%.*]]
 ; CHECK:       while.cond.while.end_crit_edge:
-; CHECK-NEXT:    [[TMP3:%.*]] = sub i32 [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[SUB_LCSSA:%.*]] = phi i32 [ [[SUB]], [[WHILE_BODY]] ]
 ; CHECK-NEXT:    br label [[WHILE_END]]
 ; CHECK:       while.end:
-; CHECK-NEXT:    [[KEYLEN_0_LCSSA:%.*]] = phi i32 [ [[TMP3]], [[WHILE_COND_WHILE_END_CRIT_EDGE]] ], [ [[LEN]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[KEYLEN_0_LCSSA:%.*]] = phi i32 [ [[SUB_LCSSA]], [[WHILE_COND_WHILE_END_CRIT_EDGE]] ], [ [[LEN]], [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    call void @_Z3mixRjj(i32* dereferenceable(4) [[A]], i32 [[KEYLEN_0_LCSSA]])
 ; CHECK-NEXT:    [[T4:%.*]] = load i32, i32* [[A]], align 4
 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[T]])
Index: llvm/test/Transforms/IndVarSimplify/elim-extend.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/elim-extend.ll
+++ llvm/test/Transforms/IndVarSimplify/elim-extend.ll
@@ -135,8 +135,8 @@
 ; CHECK-NEXT:    store i8 0, i8* [[ADR2]]
 ; CHECK-NEXT:    [[ADR3:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[INDVARS_IV_NEXT]]
 ; CHECK-NEXT:    store i8 0, i8* [[ADR3]]
-; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP0]]
-; CHECK-NEXT:    br i1 [[EXITCOND]], label [[INNERLOOP]], label [[INNEREXIT:%.*]]
+; CHECK-NEXT:    [[INNERCMP:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV_NEXT]]
+; CHECK-NEXT:    br i1 [[INNERCMP]], label [[INNERLOOP]], label [[INNEREXIT:%.*]]
 ; CHECK:       innerexit:
 ; CHECK-NEXT:    [[INNERCOUNT_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV_NEXT]], [[INNERLOOP]] ]
 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[INNERCOUNT_LCSSA_WIDE]] to i32
Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -2222,6 +2222,47 @@
                                      TTI, Processed);
   }
 
+  if (S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr) {
+    const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(S);
+
+    unsigned Opcode;
+    switch (S->getSCEVType()) {
+    case scAddExpr:
+      Opcode = Instruction::Add;
+      break;
+    case scMulExpr:
+      Opcode = Instruction::Mul;
+      break;
+    default:
+      llvm_unreachable("There are no other variants here.");
+    }
+
+    Type *OpType = NAry->getType();
+    int PairCost = TTI->getOperationCost(Opcode, OpType);
+
+    assert(NAry->getNumOperands() > 1 &&
+           "Nary expr should have more than 1 operand.");
+    for (const SCEV *Op : NAry->operands()) {
+      if (isHighCostExpansionHelper(Op, L, At, BudgetRemaining, TTI, Processed))
+        return true;
+      switch (S->getSCEVType()) {
+      case scAddExpr:
+        Opcode = Instruction::Add;
+        break;
+      case scMulExpr:
+        Opcode = Instruction::Mul;
+        break;
+      default:
+        llvm_unreachable("There are no other variants here.");
+      }
+      if (Op == *NAry->op_begin())
+        continue;
+      BudgetRemaining -= PairCost;
+    }
+
+    return BudgetRemaining < 0;
+  }
+
   // HowManyLessThans uses a Max expression whenever the loop is not guarded by
   // the exit condition.
   if (isa<SCEVMinMaxExpr>(S))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73728.241501.patch
Type: text/x-patch
Size: 4298 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200130/7c5d4aeb/attachment.bin>


More information about the llvm-commits mailing list