diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 00f4118d538d..fb30a4545cff 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -35,6 +35,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Operator.h" #include "llvm/IR/PatternMatch.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" @@ -4546,18 +4547,24 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { Value *And = nullptr, *OtherVal = nullptr; // select(C0, select(C1, a, b), b) -> select(C0&&C1, a, b) if (TrueSI->getFalseValue() == FalseVal) { - And = Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition()); + And = Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition(), "", + ProfcheckDisableMetadataFixes ? nullptr + : &SI); OtherVal = TrueSI->getTrueValue(); } // select(C0, select(C1, b, a), b) -> select(C0&&!C1, a, b) else if (TrueSI->getTrueValue() == FalseVal) { Value *InvertedCond = Builder.CreateNot(TrueSI->getCondition()); - And = Builder.CreateLogicalAnd(CondVal, InvertedCond); + And = Builder.CreateLogicalAnd(CondVal, InvertedCond, "", + ProfcheckDisableMetadataFixes ? nullptr + : &SI); OtherVal = TrueSI->getFalseValue(); } if (And && OtherVal) { replaceOperand(SI, 0, And); replaceOperand(SI, 1, OtherVal); + if (!ProfcheckDisableMetadataFixes) + setExplicitlyUnknownBranchWeightsIfProfiled(SI, DEBUG_TYPE); return &SI; } } @@ -4575,18 +4582,24 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { Value *Or = nullptr, *OtherVal = nullptr; // select(C0, a, select(C1, a, b)) -> select(C0||C1, a, b) if (FalseSI->getTrueValue() == TrueVal) { - Or = Builder.CreateLogicalOr(CondVal, FalseSI->getCondition()); + Or = Builder.CreateLogicalOr(CondVal, FalseSI->getCondition(), "", + ProfcheckDisableMetadataFixes ? nullptr + : &SI); OtherVal = FalseSI->getFalseValue(); } // select(C0, a, select(C1, b, a)) -> select(C0||!C1, a, b) else if (FalseSI->getFalseValue() == TrueVal) { Value *InvertedCond = Builder.CreateNot(FalseSI->getCondition()); - Or = Builder.CreateLogicalOr(CondVal, InvertedCond); + Or = Builder.CreateLogicalOr(CondVal, InvertedCond, "", + ProfcheckDisableMetadataFixes ? nullptr + : &SI); OtherVal = FalseSI->getTrueValue(); } if (Or && OtherVal) { replaceOperand(SI, 0, Or); replaceOperand(SI, 2, OtherVal); + if (!ProfcheckDisableMetadataFixes) + setExplicitlyUnknownBranchWeightsIfProfiled(SI, DEBUG_TYPE); return &SI; } } diff --git a/llvm/test/Transforms/InstCombine/select-select.ll b/llvm/test/Transforms/InstCombine/select-select.ll index 1693c9cf3da2..e4a7b8f73143 100644 --- a/llvm/test/Transforms/InstCombine/select-select.ll +++ b/llvm/test/Transforms/InstCombine/select-select.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals ; RUN: opt -passes=instcombine -S < %s | FileCheck %s define float @foo1(float %a) { @@ -533,49 +533,49 @@ define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison3(<2 x i32> %a, <2 x i32> ; Minimal code that triggers the optimizations. -define i32 @selectSelect11(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) { +define i32 @selectSelect11(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) !prof !0 { ; CHECK-LABEL: @selectSelect11( -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND2:%.*]], i1 true, i1 [[COND1:%.*]] -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP1]], i32 [[VAR:%.*]], i32 [[DEFAULTVAL:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND2:%.*]], i1 true, i1 [[COND1:%.*]], !prof [[PROF1:![0-9]+]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP1]], i32 [[DEFAULTVAL:%.*]], i32 [[VAR:%.*]], !prof [[PROF2:![0-9]+]] ; CHECK-NEXT: ret i32 [[SEL2]] ; - %sel1 = select i1 %cond1, i32 %defaultVal, i32 %var - %sel2 = select i1 %cond2, i32 %defaultVal, i32 %sel1 + %sel1 = select i1 %cond1, i32 %defaultVal, i32 %var, !prof !1 + %sel2 = select i1 %cond2, i32 %defaultVal, i32 %sel1, !prof !2 ret i32 %sel2 } -define i32 @selectSelect22(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) { +define i32 @selectSelect22(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) !prof !0 { ; CHECK-LABEL: @selectSelect22( -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND2:%.*]], i1 [[COND1:%.*]], i1 false -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP1]], i32 [[VAR:%.*]], i32 [[DEFAULTVAL:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND2:%.*]], i1 [[COND1:%.*]], i1 false, !prof [[PROF1]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP1]], i32 [[VAR:%.*]], i32 [[DEFAULTVAL:%.*]], !prof [[PROF2]] ; CHECK-NEXT: ret i32 [[SEL2]] ; - %sel1 = select i1 %cond1, i32 %var, i32 %defaultVal - %sel2 = select i1 %cond2, i32 %sel1, i32 %defaultVal + %sel1 = select i1 %cond1, i32 %var, i32 %defaultVal, !prof !1 + %sel2 = select i1 %cond2, i32 %sel1, i32 %defaultVal, !prof !2 ret i32 %sel2 } -define i32 @selectSelect12(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) { +define i32 @selectSelect12(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) !prof !0 { ; CHECK-LABEL: @selectSelect12( ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[COND1:%.*]], true -; CHECK-NEXT: [[COND2:%.*]] = select i1 [[COND3:%.*]], i1 [[TMP1]], i1 false -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND2]], i32 [[SEL3:%.*]], i32 [[DEFAULTVAL:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND2:%.*]], i1 [[TMP1]], i1 false, !prof [[PROF1]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP2]], i32 [[VAR:%.*]], i32 [[DEFAULTVAL:%.*]], !prof [[PROF2]] ; CHECK-NEXT: ret i32 [[SEL2]] ; - %sel1 = select i1 %cond1, i32 %defaultVal,i32 %var - %sel2 = select i1 %cond2, i32 %sel1, i32 %defaultVal + %sel1 = select i1 %cond1, i32 %defaultVal,i32 %var, !prof !1 + %sel2 = select i1 %cond2, i32 %sel1, i32 %defaultVal, !prof !2 ret i32 %sel2 } -define i32 @selectSelect21(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) { +define i32 @selectSelect21(i1 %cond1, i1 %cond2, i32 %var, i32 %defaultVal) !prof !0 { ; CHECK-LABEL: @selectSelect21( ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[COND1:%.*]], true -; CHECK-NEXT: [[COND2:%.*]] = select i1 [[COND3:%.*]], i1 true, i1 [[TMP1]] -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND2]], i32 [[DEFAULTVAL1:%.*]], i32 [[DEFAULTVAL:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND2:%.*]], i1 true, i1 [[TMP1]], !prof [[PROF1]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP2]], i32 [[DEFAULTVAL:%.*]], i32 [[VAR:%.*]], !prof [[PROF2]] ; CHECK-NEXT: ret i32 [[SEL2]] ; - %sel1 = select i1 %cond1, i32 %var, i32 %defaultVal - %sel2 = select i1 %cond2, i32 %defaultVal, i32 %sel1 + %sel1 = select i1 %cond1, i32 %var, i32 %defaultVal, !prof !1 + %sel2 = select i1 %cond2, i32 %defaultVal, i32 %sel1, !prof !2 ret i32 %sel2 } @@ -689,3 +689,14 @@ define i32 @gh82350(i32 %x, i32 %y, i32 %z, i1 %cmp1) { declare void @use1(i1) declare void @use8(i8) declare void @use32(i32) + +!0 = !{!"function_entry_count", i64 1000} +!1 = !{!"branch_weights", i32 2, i32 3} +!2 = !{!"branch_weights", i32 5, i32 3} +;. +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) } +;. +; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000} +; CHECK: [[PROF1]] = !{!"branch_weights", i32 5, i32 3} +; CHECK: [[PROF2]] = !{!"unknown", !"instcombine"} +;.