Index: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp @@ -776,6 +776,31 @@ return false; } +// Set branch weights on SwitchInst. This sets the metadata if there is at +// least one non-zero weight. +static void setBranchWeights(SwitchInst *SI, ArrayRef Weights) { + // Check that there is at least one non-zero weight. Otherwise, pass + // nullptr to setMetadata which will erase the existing metadata. + MDNode *N = nullptr; + if (llvm::any_of(Weights, [](uint32_t W) { return W != 0; })) + N = MDBuilder(SI->getParent()->getContext()).createBranchWeights(Weights); + SI->setMetadata(LLVMContext::MD_prof, N); +} + +// Similar to the above, but for branch and select instructions that take +// exactly 2 weights. +static void setBranchWeights(Instruction *I, uint32_t TrueWeight, + uint32_t FalseWeight) { + assert(isa(I) || isa(I)); + // Check that there is at least one non-zero weight. Otherwise, pass + // nullptr to setMetadata which will erase the existing metadata. + MDNode *N = nullptr; + if (TrueWeight || FalseWeight) + N = MDBuilder(I->getParent()->getContext()) + .createBranchWeights(TrueWeight, FalseWeight); + I->setMetadata(LLVMContext::MD_prof, N); +} + /// If TI is known to be a terminator instruction and its block is known to /// only have a single predecessor block, check to see if that predecessor is /// also a value comparison with the same value, and if that comparison @@ -865,9 +890,7 @@ } } if (HasWeight && Weights.size() >= 2) - SI->setMetadata(LLVMContext::MD_prof, - MDBuilder(SI->getParent()->getContext()) - .createBranchWeights(Weights)); + setBranchWeights(SI, Weights); DEBUG(dbgs() << "Leaving: " << *TI << "\n"); return true; @@ -1172,9 +1195,7 @@ SmallVector MDWeights(Weights.begin(), Weights.end()); - NewSI->setMetadata( - LLVMContext::MD_prof, - MDBuilder(BB->getContext()).createBranchWeights(MDWeights)); + setBranchWeights(NewSI, MDWeights); } EraseTerminatorInstAndDCECond(PTI); @@ -2738,9 +2759,7 @@ SmallVector MDWeights(NewWeights.begin(), NewWeights.end()); - PBI->setMetadata( - LLVMContext::MD_prof, - MDBuilder(BI->getContext()).createBranchWeights(MDWeights)); + setBranchWeights(PBI, MDWeights[0], MDWeights[1]); } else PBI->setMetadata(LLVMContext::MD_prof, nullptr); } else { @@ -3309,9 +3328,7 @@ // Halve the weights if any of them cannot fit in an uint32_t FitWeights(NewWeights); - PBI->setMetadata(LLVMContext::MD_prof, - MDBuilder(BI->getContext()) - .createBranchWeights(NewWeights[0], NewWeights[1])); + setBranchWeights(PBI, NewWeights[0], NewWeights[1]); } // OtherDest may have phi nodes. If so, add an entry from PBI's @@ -3349,9 +3366,7 @@ FitWeights(NewWeights); - NV->setMetadata(LLVMContext::MD_prof, - MDBuilder(BI->getContext()) - .createBranchWeights(NewWeights[0], NewWeights[1])); + setBranchWeights(NV, NewWeights[0], NewWeights[1]); } } } @@ -3406,9 +3421,7 @@ // Create a conditional branch sharing the condition of the select. BranchInst *NewBI = Builder.CreateCondBr(Cond, TrueBB, FalseBB); if (TrueWeight != FalseWeight) - NewBI->setMetadata(LLVMContext::MD_prof, - MDBuilder(OldTerm->getContext()) - .createBranchWeights(TrueWeight, FalseWeight)); + setBranchWeights(NewBI, TrueWeight, FalseWeight); } } else if (KeepEdge1 && (KeepEdge2 || TrueBB == FalseBB)) { // Neither of the selected blocks were successors, so this @@ -3594,9 +3607,7 @@ Weights.push_back(Weights[0]); SmallVector MDWeights(Weights.begin(), Weights.end()); - SI->setMetadata( - LLVMContext::MD_prof, - MDBuilder(SI->getContext()).createBranchWeights(MDWeights)); + setBranchWeights(SI, MDWeights); } } SI->addCase(Cst, NewBB); @@ -4323,10 +4334,7 @@ TrueWeight /= 2; FalseWeight /= 2; } - NewBI->setMetadata(LLVMContext::MD_prof, - MDBuilder(SI->getContext()) - .createBranchWeights((uint32_t)TrueWeight, - (uint32_t)FalseWeight)); + setBranchWeights(NewBI, TrueWeight, FalseWeight); } } @@ -4423,9 +4431,7 @@ } if (HasWeight && Weights.size() >= 2) { SmallVector MDWeights(Weights.begin(), Weights.end()); - SI->setMetadata(LLVMContext::MD_prof, - MDBuilder(SI->getParent()->getContext()) - .createBranchWeights(MDWeights)); + setBranchWeights(SI, MDWeights); } return !DeadCases.empty(); Index: llvm/trunk/test/Transforms/SimplifyCFG/suppress-zero-branch-weights.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/suppress-zero-branch-weights.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/suppress-zero-branch-weights.ll @@ -0,0 +1,39 @@ +; RUN: opt -S -simplifycfg < %s | FileCheck %s + +; We're sign extending an 8-bit value. +; The switch condition must be in the range [-128, 127], so any cases outside of that range must be dead. +; Only the first case has a non-zero weight, but that gets eliminated. Note +; that this shouldn't have been the case in the first place, but the test here +; ensures that all-zero branch weights are not attached causing problems downstream. + +define i1 @repeated_signbits(i8 %condition) { +; CHECK-LABEL: @repeated_signbits( +; CHECK: switch i32 +; CHECK-DAG: i32 -128, label %a +; CHECK-DAG: i32 -1, label %a +; CHECK-DAG: i32 0, label %a +; CHECK-DAG: i32 127, label %a +; CHECK-NEXT: ] +; +entry: + %sext = sext i8 %condition to i32 + switch i32 %sext, label %default [ + i32 -2147483648, label %a + i32 -129, label %a + i32 -128, label %a + i32 -1, label %a + i32 0, label %a + i32 127, label %a + i32 128, label %a + i32 2147483647, label %a + ], !prof !1 + +a: + ret i1 1 + +default: + ret i1 0 +} + +!1 = !{!"branch_weights", i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0} +