From: Ayonam Ray Date: Tue, 1 Jan 2019 07:28:55 +0000 (+0000) Subject: Reversing the commit in revision 350186. Revision causes regression in 4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=81b403db2959d4e2458660c6c4d8e0c298aa2b1a;p=llvm Reversing the commit in revision 350186. Revision causes regression in 4 tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350187 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 2cca7e077e4..d64b96b3874 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2189,30 +2189,24 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, JumpTableReg, SwitchOp); JT.Reg = JumpTableReg; - if (!JTH.OmitRangeCheck) { - // Emit the range check for the jump table, and branch to the default block - // for the switch statement if the value being switched on exceeds the - // largest case in the switch. - SDValue CMP = DAG.getSetCC( - dl, TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), - Sub.getValueType()), - Sub, DAG.getConstant(JTH.Last - JTH.First, dl, VT), ISD::SETUGT); - - SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, - MVT::Other, CopyTo, CMP, - DAG.getBasicBlock(JT.Default)); - - // Avoid emitting unnecessary branches to the next block. - if (JT.MBB != NextBlock(SwitchBB)) - BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond, - DAG.getBasicBlock(JT.MBB)); - - DAG.setRoot(BrCond); - } else { - SDValue BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, CopyTo, - DAG.getBasicBlock(JT.MBB)); - DAG.setRoot(BrCond); - } + // Emit the range check for the jump table, and branch to the default block + // for the switch statement if the value being switched on exceeds the largest + // case in the switch. + SDValue CMP = DAG.getSetCC( + dl, TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), + Sub.getValueType()), + Sub, DAG.getConstant(JTH.Last - JTH.First, dl, VT), ISD::SETUGT); + + SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, + MVT::Other, CopyTo, CMP, + DAG.getBasicBlock(JT.Default)); + + // Avoid emitting unnecessary branches to the next block. + if (JT.MBB != NextBlock(SwitchBB)) + BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond, + DAG.getBasicBlock(JT.MBB)); + + DAG.setRoot(BrCond); } /// Create a LOAD_STACK_GUARD node, and let it carry the target specific global @@ -9564,13 +9558,10 @@ bool SelectionDAGBuilder::buildJumpTable(const CaseClusterVector &Clusters, ->createJumpTableIndex(Table); // Set up the jump table info. - bool UnreachableDefault = - isa(SI->getDefaultDest()->getFirstNonPHIOrDbg()); - bool OmitRangeCheck = UnreachableDefault; JumpTable JT(-1U, JTI, JumpTableMBB, nullptr); JumpTableHeader JTH(Clusters[First].Low->getValue(), Clusters[Last].High->getValue(), SI->getCondition(), - nullptr, false, OmitRangeCheck); + nullptr, false); JTCases.emplace_back(std::move(JTH), std::move(JT)); JTCluster = CaseCluster::jumpTable(Clusters[First].Low, Clusters[Last].High, @@ -10307,7 +10298,6 @@ MachineBasicBlock *SelectionDAGBuilder::peelDominantCaseCluster( const SwitchInst &SI, CaseClusterVector &Clusters, BranchProbability &PeeledCaseProb) { MachineBasicBlock *SwitchMBB = FuncInfo.MBB; - // Don't perform if there is only one cluster or optimizing for size. if (SwitchPeelThreshold > 100 || !FuncInfo.BPI || Clusters.size() < 2 || TM.getOptLevel() == CodeGenOpt::None || @@ -10360,7 +10350,6 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { // Extract cases from the switch. BranchProbabilityInfo *BPI = FuncInfo.BPI; CaseClusterVector Clusters; - Clusters.reserve(SI.getNumCases()); for (auto I : SI.cases()) { MachineBasicBlock *Succ = FuncInfo.MBBMap[I.getCaseSuccessor()]; @@ -10378,6 +10367,38 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { // if there are many clusters. sortAndRangeify(Clusters); + if (TM.getOptLevel() != CodeGenOpt::None) { + // Replace an unreachable default with the most popular destination. + // FIXME: Exploit unreachable default more aggressively. + bool UnreachableDefault = + isa(SI.getDefaultDest()->getFirstNonPHIOrDbg()); + if (UnreachableDefault && !Clusters.empty()) { + DenseMap Popularity; + unsigned MaxPop = 0; + const BasicBlock *MaxBB = nullptr; + for (auto I : SI.cases()) { + const BasicBlock *BB = I.getCaseSuccessor(); + if (++Popularity[BB] > MaxPop) { + MaxPop = Popularity[BB]; + MaxBB = BB; + } + } + // Set new default. + assert(MaxPop > 0 && MaxBB); + DefaultMBB = FuncInfo.MBBMap[MaxBB]; + + // Remove cases that were pointing to the destination that is now the + // default. + CaseClusterVector New; + New.reserve(Clusters.size()); + for (CaseCluster &CC : Clusters) { + if (CC.MBB != DefaultMBB) + New.push_back(CC); + } + Clusters = std::move(New); + } + } + // The branch probablity of the peeled case. BranchProbability PeeledCaseProb = BranchProbability::getZero(); MachineBasicBlock *PeeledSwitchMBB = diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index d2fb8e28ff3..5f9cdb69daf 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -279,12 +279,11 @@ private: const Value *SValue; MachineBasicBlock *HeaderBB; bool Emitted; - bool OmitRangeCheck; JumpTableHeader(APInt F, APInt L, const Value *SV, MachineBasicBlock *H, - bool E = false, bool ORC = false) + bool E = false) : First(std::move(F)), Last(std::move(L)), SValue(SV), HeaderBB(H), - Emitted(E), OmitRangeCheck(ORC) {} + Emitted(E) {} }; using JumpTableBlock = std::pair; diff --git a/test/CodeGen/AArch64/switch-unreachable-default.ll b/test/CodeGen/AArch64/switch-unreachable-default.ll deleted file mode 100644 index 7ddcd51cc02..00000000000 --- a/test/CodeGen/AArch64/switch-unreachable-default.ll +++ /dev/null @@ -1,62 +0,0 @@ -; RUN: llc -O3 -o - %s | FileCheck %s - -; Test that the output in the presence of an unreachable default does not have -; a compare and branch at the top of the switch to handle the default case. - -target triple = "aarch64-unknown-linux-gnu" - -; Function Attrs: nounwind -define void @fn(i4) { - switch i4 %0, label %default [ - i4 0, label %case_0 - i4 1, label %case_1 - i4 2, label %case_2 - i4 3, label %case_3 - i4 4, label %case_4 - i4 5, label %case_5 - ] - -; CHECK-LABEL: fn: -; CHECK-NOT: sub -; CHECK-NOT: cmp -; CHECK-NOT: b.hi -; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3] -; CHECK: br {{x[0-9]+}} - -default: - unreachable - -case_0: - tail call void @handle_case_00(i4 %0) #2 - br label %return_label - -case_1: - tail call void @handle_case_01(i4 %0) #2 - br label %return_label - -case_2: - tail call void @handle_case_02(i4 %0) #2 - br label %return_label - -case_3: - tail call void @handle_case_03(i4 %0) #2 - br label %return_label - -case_4: - tail call void @handle_case_04(i4 %0) #2 - br label %return_label - -case_5: - tail call void @handle_case_05(i4 %0) #2 - br label %return_label - -return_label: - ret void -} - -declare void @handle_case_00(i4) -declare void @handle_case_01(i4) -declare void @handle_case_02(i4) -declare void @handle_case_03(i4) -declare void @handle_case_04(i4) -declare void @handle_case_05(i4)