[llvm] r222877 - Revert "Peephole optimization in switch table lookup: reuse the guarding table comparison if possible."

Erik Eckstein eeckstein at apple.com
Thu Nov 27 02:59:09 PST 2014


Author: eeckstein
Date: Thu Nov 27 04:59:08 2014
New Revision: 222877

URL: http://llvm.org/viewvc/llvm-project?rev=222877&view=rev
Log:
Revert "Peephole optimization in switch table lookup: reuse the guarding table comparison if possible."

It is breaking the clang bootstrag.


Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=222877&r1=222876&r2=222877&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Nov 27 04:59:08 2014
@@ -73,7 +73,6 @@ STATISTIC(NumBitMaps, "Number of switch
 STATISTIC(NumLinearMaps, "Number of switch instructions turned into linear mapping");
 STATISTIC(NumLookupTables, "Number of switch instructions turned into lookup tables");
 STATISTIC(NumLookupTablesHoles, "Number of switch instructions turned into lookup tables (holes checked)");
-STATISTIC(NumTableCmpReuses, "Number of reused switch table lookup compares");
 STATISTIC(NumSinkCommons, "Number of common instructions sunk down to the end block");
 STATISTIC(NumSpeculations, "Number of speculative executed instructions");
 
@@ -3983,78 +3982,6 @@ static bool ShouldBuildLookupTable(Switc
   return SI->getNumCases() * 10 >= TableSize * 4;
 }
 
-/// Try to reuse the switch table index compare. Following pattern:
-/// \code
-///     if (idx < tablesize)
-///        r = table[idx]; // table does not contain default_value
-///     else
-///        r = default_value;
-///     if (r != default_value)
-///        ...
-/// \endcode
-/// Is optimized to:
-/// \code
-///     cond = idx < tablesize;
-///     if (cond)
-///        r = table[idx];
-///     else
-///        r = default_value;
-///     if (cond)
-///        ...
-/// \endcode
-/// Jump threading will then eliminate the second if(cond).
-static void reuseTableCompare(User *PhiUser, BasicBlock *PhiBlock,
-          BranchInst *RangeCheckBranch, Constant *DefaultValue,
-          const SmallVectorImpl<std::pair<ConstantInt*, Constant*> >& Values) {
-
-  ICmpInst *CmpInst = dyn_cast<ICmpInst>(PhiUser);
-  if (!CmpInst)
-    return;
-
-  // We require that the compare is in the same block as the phi so that jump
-  // threading can do its work afterwards.
-  if (CmpInst->getParent() != PhiBlock)
-    return;
-
-  Constant *CmpOp1 = dyn_cast<Constant>(CmpInst->getOperand(1));
-  if (!CmpOp1)
-    return;
-
-  Value *RangeCmp = RangeCheckBranch->getCondition();
-  Constant *TrueConst = ConstantInt::getTrue(RangeCmp->getType());
-  Constant *FalseConst = ConstantInt::getFalse(RangeCmp->getType());
-
-  // Check if the compare with the default value is constant true or false.
-  Constant *DefaultConst = ConstantExpr::getICmp(CmpInst->getPredicate(),
-                                                 DefaultValue, CmpOp1, true);
-  if (DefaultConst != TrueConst && DefaultConst != FalseConst)
-    return;
-
-  // Check if the compare with the case values is distinct from the default
-  // compare result.
-  for (auto ValuePair : Values) {
-    Constant *CaseConst = ConstantExpr::getICmp(CmpInst->getPredicate(),
-                              ValuePair.second, CmpOp1, true);
-    if (!CaseConst || CaseConst == DefaultConst)
-      return;
-    assert((CaseConst == TrueConst || CaseConst == FalseConst) &&
-           "Expect true or false as compare result.");
-  }
-
-  if (DefaultConst == FalseConst) {
-    // The compare yields the same result. We can replace it.
-    CmpInst->replaceAllUsesWith(RangeCmp);
-    ++NumTableCmpReuses;
-  } else {
-    // The compare yields the same result, just inverted. We can replace it.
-    Value *InvertedTableCmp = BinaryOperator::CreateXor(RangeCmp,
-                ConstantInt::get(RangeCmp->getType(), 1), "inverted.cmp",
-                RangeCheckBranch);
-    CmpInst->replaceAllUsesWith(InvertedTableCmp);
-    ++NumTableCmpReuses;
-  }
-}
-
 /// SwitchToLookupTable - If the switch is only used to initialize one or more
 /// phi nodes in a common successor block with different constant values,
 /// replace the switch with lookup tables.
@@ -4131,8 +4058,11 @@ static bool SwitchToLookupTable(SwitchIn
   // If the table has holes, we need a constant result for the default case
   // or a bitmask that fits in a register.
   SmallVector<std::pair<PHINode*, Constant*>, 4> DefaultResultsList;
-  bool HasDefaultResults = GetCaseResults(SI, nullptr, SI->getDefaultDest(),
+  bool HasDefaultResults = false;
+  if (TableHasHoles) {
+    HasDefaultResults = GetCaseResults(SI, nullptr, SI->getDefaultDest(),
                                        &CommonDest, DefaultResultsList, DL);
+  }
 
   bool NeedMask = (TableHasHoles && !HasDefaultResults);
   if (NeedMask) {
@@ -4176,8 +4106,6 @@ static bool SwitchToLookupTable(SwitchIn
   // lookup table BB. Otherwise, check if the condition value is within the case
   // range. If it is so, branch to the new BB. Otherwise branch to SI's default
   // destination.
-  BranchInst *RangeCheckBranch = nullptr;
-
   const bool GeneratingCoveredLookupTable = MaxTableSize == TableSize;
   if (GeneratingCoveredLookupTable) {
     Builder.CreateBr(LookupBB);
@@ -4188,7 +4116,7 @@ static bool SwitchToLookupTable(SwitchIn
   } else {
     Value *Cmp = Builder.CreateICmpULT(TableIndex, ConstantInt::get(
                                        MinCaseVal->getType(), TableSize));
-    RangeCheckBranch = Builder.CreateCondBr(Cmp, LookupBB, SI->getDefaultDest());
+    Builder.CreateCondBr(Cmp, LookupBB, SI->getDefaultDest());
   }
 
   // Populate the BB that does the lookups.
@@ -4239,11 +4167,11 @@ static bool SwitchToLookupTable(SwitchIn
   bool ReturnedEarly = false;
   for (size_t I = 0, E = PHIs.size(); I != E; ++I) {
     PHINode *PHI = PHIs[I];
-    const ResultListTy &ResultList = ResultLists[PHI];
 
     // If using a bitmask, use any value to fill the lookup table holes.
     Constant *DV = NeedMask ? ResultLists[PHI][0].second : DefaultResults[PHI];
-    SwitchLookupTable Table(Mod, TableSize, MinCaseVal, ResultList, DV, DL);
+    SwitchLookupTable Table(Mod, TableSize, MinCaseVal, ResultLists[PHI],
+                            DV, DL);
 
     Value *Result = Table.BuildLookup(TableIndex, Builder);
 
@@ -4256,16 +4184,6 @@ static bool SwitchToLookupTable(SwitchIn
       break;
     }
 
-    // Do a small peephole optimization: re-use the switch table compare if
-    // possible.
-    if (!TableHasHoles && HasDefaultResults && RangeCheckBranch) {
-      BasicBlock *PhiBlock = PHI->getParent();
-      // Search for compare instructions which use the phi.
-      for (auto *User : PHI->users()) {
-        reuseTableCompare(User, PhiBlock, RangeCheckBranch, DV, ResultList);
-      }
-    }
-
     PHI->addIncoming(Result, LookupBB);
   }
 

Modified: llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll?rev=222877&r1=222876&r2=222877&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll Thu Nov 27 04:59:08 2014
@@ -1077,97 +1077,3 @@ return:
 ; CHECK-NEXT: ret i8 %switch.idx.cast
 }
 
-; Reuse the inverted table range compare.
-define i32 @reuse_cmp1(i32 %x) {
-entry:
-  switch i32 %x, label %sw.default [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-    i32 3, label %sw.bb3
-  ]
-sw.bb: br label %sw.epilog
-sw.bb1: br label %sw.epilog
-sw.bb2: br label %sw.epilog
-sw.bb3: br label %sw.epilog
-sw.default: br label %sw.epilog
-sw.epilog:
-  %r.0 = phi i32 [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
-  %cmp = icmp eq i32 %r.0, 0       ; This compare can be "replaced".
-  br i1 %cmp, label %if.then, label %if.end
-if.then: br label %return
-if.end: br label %return
-return:
-  %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
-  ret i32 %retval.0
-; CHECK-LABEL: @reuse_cmp1(
-; CHECK: entry:
-; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
-; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
-; CHECK-NEXT: %inverted.cmp = xor i1 [[C]], true
-; CHECK:      [[R:%.+]] = select i1 %inverted.cmp, i32 100, i32 {{.*}}
-; CHECK-NEXT: ret i32 [[R]]
-}
-
-; Reuse the table range compare.
-define i32 @reuse_cmp2(i32 %x) {
-entry:
-  switch i32 %x, label %sw.default [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-    i32 3, label %sw.bb3
-  ]
-sw.bb: br label %sw.epilog
-sw.bb1: br label %sw.epilog
-sw.bb2: br label %sw.epilog
-sw.bb3: br label %sw.epilog
-sw.default: br label %sw.epilog
-sw.epilog:
-  %r.0 = phi i32 [ 4, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %sw.bb ]
-  %cmp = icmp ne i32 %r.0, 4       ; This compare can be "replaced".
-  br i1 %cmp, label %if.then, label %if.end
-if.then: br label %return
-if.end: br label %return
-return:
-  %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
-  ret i32 %retval.0
-; CHECK-LABEL: @reuse_cmp2(
-; CHECK: entry:
-; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
-; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
-; CHECK:      [[R:%.+]] = select i1 [[C]], i32 {{.*}}, i32 100
-; CHECK-NEXT: ret i32 [[R]]
-}
-
-; Cannot reuse the table range compare, because the default value is the same
-; as one of the case values.
-define i32 @no_reuse_cmp(i32 %x) {
-entry:
-  switch i32 %x, label %sw.default [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-    i32 3, label %sw.bb3
-  ]
-sw.bb: br label %sw.epilog
-sw.bb1: br label %sw.epilog
-sw.bb2: br label %sw.epilog
-sw.bb3: br label %sw.epilog
-sw.default: br label %sw.epilog
-sw.epilog:
-  %r.0 = phi i32 [ 12, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
-  %cmp = icmp ne i32 %r.0, 0
-  br i1 %cmp, label %if.then, label %if.end
-if.then: br label %return
-if.end: br label %return
-return:
-  %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
-  ret i32 %retval.0
-; CHECK-LABEL: @no_reuse_cmp(
-; CHECK:  [[S:%.+]] = select 
-; CHECK-NEXT:  %cmp = icmp ne i32 [[S]], 0
-; CHECK-NEXT:  [[R:%.+]] = select i1 %cmp, i32 [[S]], i32 100
-; CHECK-NEXT:  ret i32 [[R]]
-}
-





More information about the llvm-commits mailing list