Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -1577,12 +1577,16 @@ } Value *CreateSelect(Value *C, Value *True, Value *False, - const Twine &Name = "") { + const Twine &Name = "", MDNode *ProfWeights = nullptr) { if (Constant *CC = dyn_cast(C)) if (Constant *TC = dyn_cast(True)) if (Constant *FC = dyn_cast(False)) return Insert(Folder.CreateSelect(CC, TC, FC), Name); - return Insert(SelectInst::Create(C, True, False), Name); + + SelectInst *Sel = SelectInst::Create(C, True, False); + // TODO: "unpredictable" metadata can apply to a select too. + Sel->setMetadata(LLVMContext::MD_prof, ProfWeights); + return Insert(Sel, Name); } VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") { Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -1935,7 +1935,8 @@ Value *TrueVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfFalse); Value *FalseVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfTrue); - Value *Select = Builder.CreateSelect(IfCond, TrueVal, FalseVal); + MDNode *MDN = InsertPt->getMetadata(LLVMContext::MD_prof); + Value *Select = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", MDN); PN->replaceAllUsesWith(Select); Select->takeName(PN); PN->eraseFromParent(); Index: test/Transforms/SimplifyCFG/preserve-branchweights.ll =================================================================== --- test/Transforms/SimplifyCFG/preserve-branchweights.ll +++ test/Transforms/SimplifyCFG/preserve-branchweights.ll @@ -364,6 +364,35 @@ ret void } +; PR26636: The branch metadata should get propagated to the select. + +define i32 @FoldTwoEntryPHINode(i32 %x) #0 { +entry: + %cmp = icmp sgt i32 %x, 4 + br i1 %cmp, label %if.then, label %if.end, !prof !12 + +if.then: + %add = add nsw i32 %x, 7 + br label %return + +if.end: + %mul = mul nsw i32 %x, 17 + br label %return + +return: + %retval.0 = phi i32 [ %add, %if.then ], [ %mul, %if.end ] + ret i32 %retval.0 + +; CHECK-LABEL: @FoldTwoEntryPHINode( +; CHECK-NEXT: entry: +; CHECK-NEXT: %cmp = icmp sgt i32 %x, 4 +; CHECK-NEXT: %add = add nsw i32 %x, 7 +; CHECK-NEXT: %mul = mul nsw i32 %x, 17 +; CHECK-NEXT: %retval.0 = select i1 %cmp, i32 %add, i32 %mul, !prof !11 +; CHECK-NEXT: ret i32 %retval.0 +} + + !0 = !{!"branch_weights", i32 3, i32 5} !1 = !{!"branch_weights", i32 1, i32 1} !2 = !{!"branch_weights", i32 1, i32 2} @@ -376,6 +405,7 @@ !9 = !{!"branch_weights", i32 7, i32 6} !10 = !{!"branch_weights", i32 672646, i32 21604207} !11 = !{!"branch_weights", i32 6960, i32 21597248} +!12 = !{!"branch_weights", i32 6, i32 2000} ; CHECK: !0 = !{!"branch_weights", i32 5, i32 11} ; CHECK: !1 = !{!"branch_weights", i32 1, i32 5} @@ -390,3 +420,4 @@ ;; The false weight prints out as a negative integer here, but inside llvm, we ;; treat the weight as an unsigned integer. ; CHECK: !10 = !{!"branch_weights", i32 112017436, i32 -735157296} +; CHECK: !11 = !{!"branch_weights", i32 6, i32 2000}