Skip to content

Commit a1b5e97

Browse files
authored
[InstCombine][profcheck] Preserve profile when folding constant value equivalences (#162736)
1 parent 067a110 commit a1b5e97

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ using namespace PatternMatch;
2828

2929
#define DEBUG_TYPE "instcombine"
3030

31+
namespace llvm {
32+
extern cl::opt<bool> ProfcheckDisableMetadataFixes;
33+
}
34+
3135
/// This is the complement of getICmpCode, which turns an opcode and two
3236
/// operands into either a constant true or false, or a brand new ICmp
3337
/// instruction. The sign is passed in to determine which kind of predicate to
@@ -1272,7 +1276,8 @@ Value *InstCombinerImpl::foldEqOfParts(Value *Cmp0, Value *Cmp1, bool IsAnd) {
12721276
static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
12731277
bool IsAnd, bool IsLogical,
12741278
InstCombiner::BuilderTy &Builder,
1275-
const SimplifyQuery &Q) {
1279+
const SimplifyQuery &Q,
1280+
Instruction &I) {
12761281
// Match an equality compare with a non-poison constant as Cmp0.
12771282
// Also, give up if the compare can be constant-folded to avoid looping.
12781283
CmpPredicate Pred0;
@@ -1306,9 +1311,12 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
13061311
return nullptr;
13071312
SubstituteCmp = Builder.CreateICmp(Pred1, Y, C);
13081313
}
1309-
if (IsLogical)
1310-
return IsAnd ? Builder.CreateLogicalAnd(Cmp0, SubstituteCmp)
1311-
: Builder.CreateLogicalOr(Cmp0, SubstituteCmp);
1314+
if (IsLogical) {
1315+
Instruction *MDFrom =
1316+
ProfcheckDisableMetadataFixes && isa<SelectInst>(I) ? nullptr : &I;
1317+
return IsAnd ? Builder.CreateLogicalAnd(Cmp0, SubstituteCmp, "", MDFrom)
1318+
: Builder.CreateLogicalOr(Cmp0, SubstituteCmp, "", MDFrom);
1319+
}
13121320
return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
13131321
SubstituteCmp);
13141322
}
@@ -3396,13 +3404,13 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
33963404
/*IsLogical*/ false, Builder))
33973405
return V;
33983406

3399-
if (Value *V =
3400-
foldAndOrOfICmpsWithConstEq(LHS, RHS, IsAnd, IsLogical, Builder, Q))
3407+
if (Value *V = foldAndOrOfICmpsWithConstEq(LHS, RHS, IsAnd, IsLogical,
3408+
Builder, Q, I))
34013409
return V;
34023410
// We can convert this case to bitwise and, because both operands are used
34033411
// on the LHS, and as such poison from both will propagate.
3404-
if (Value *V = foldAndOrOfICmpsWithConstEq(RHS, LHS, IsAnd,
3405-
/*IsLogical=*/false, Builder, Q)) {
3412+
if (Value *V = foldAndOrOfICmpsWithConstEq(
3413+
RHS, LHS, IsAnd, /*IsLogical=*/false, Builder, Q, I)) {
34063414
// If RHS is still used, we should drop samesign flag.
34073415
if (IsLogical && RHS->hasSameSign() && !RHS->use_empty()) {
34083416
RHS->setSameSign(false);

llvm/test/Transforms/InstCombine/select-safe-transforms.ll

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
22
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
33

44
declare i1 @gen1()
55

6+
;.
7+
; CHECK: @glb = global i8 0
8+
;.
69
define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) {
710
; CHECK-LABEL: @cond_eq_and(
811
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[C:%.*]]
@@ -16,16 +19,16 @@ define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) {
1619
ret i1 %res
1720
}
1821

19-
define i1 @cond_eq_and_const(i8 %X, i8 %Y) {
22+
define i1 @cond_eq_and_const(i8 %X, i8 %Y) !prof !0 {
2023
; CHECK-LABEL: @cond_eq_and_const(
2124
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], 10
2225
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 10
23-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[TMP1]], i1 false
26+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[TMP1]], i1 false, !prof [[PROF1:![0-9]+]]
2427
; CHECK-NEXT: ret i1 [[RES]]
2528
;
2629
%cond = icmp eq i8 %X, 10
2730
%lhs = icmp ult i8 %X, %Y
28-
%res = select i1 %cond, i1 %lhs, i1 false
31+
%res = select i1 %cond, i1 %lhs, i1 false, !prof !1
2932
ret i1 %res
3033
}
3134

@@ -42,16 +45,16 @@ define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) {
4245
ret i1 %res
4346
}
4447

45-
define i1 @cond_eq_or_const(i8 %X, i8 %Y) {
48+
define i1 @cond_eq_or_const(i8 %X, i8 %Y) !prof !0 {
4649
; CHECK-LABEL: @cond_eq_or_const(
4750
; CHECK-NEXT: [[COND:%.*]] = icmp ne i8 [[X:%.*]], 10
4851
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 10
49-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[TMP1]]
52+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[TMP1]], !prof [[PROF1]]
5053
; CHECK-NEXT: ret i1 [[RES]]
5154
;
5255
%cond = icmp ne i8 %X, 10
5356
%lhs = icmp ult i8 %X, %Y
54-
%res = select i1 %cond, i1 true, i1 %lhs
57+
%res = select i1 %cond, i1 true, i1 %lhs, !prof !1
5558
ret i1 %res
5659
}
5760

@@ -793,3 +796,10 @@ define <2 x i1> @not_logical_and2(i1 %b, <2 x i32> %a) {
793796
%or = select <2 x i1> %and, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied
794797
ret <2 x i1> %or
795798
}
799+
800+
!0 = !{!"function_entry_count", i64 1000}
801+
!1 = !{!"branch_weights", i32 2, i32 3}
802+
;.
803+
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}
804+
; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}
805+
;.

0 commit comments

Comments
 (0)