[InstCombine] Propagate profile metadata when combining selects (#177883)
When we simplify a pair of selects, we want to propagate profile information when the condition remains the same and drop it when it does not. Before this patch, we were keeping incorrect profile data in addition to not annotating any new select instructions that had the same value as a previous one. Noticed by looking at 80d9df6b054cebfbe97d709195be4e61a7acc694.
This commit is contained in:
parent
cd79290926
commit
16c8a02f2d
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"}
|
||||
;.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user