Skip to content

Commit f0420c7

Browse files
authored
[ValueTracking] Handle not in isImpliedCondition (llvm#85397)
This patch handles `not` in `isImpliedCondition` to enable more fold in some multi-use cases.
1 parent 756c205 commit f0420c7

File tree

3 files changed

+93
-10
lines changed

3 files changed

+93
-10
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8606,6 +8606,10 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred,
86068606
assert(LHS->getType()->isIntOrIntVectorTy(1) &&
86078607
"Expected integer type only!");
86088608

8609+
// Match not
8610+
if (match(LHS, m_Not(m_Value(LHS))))
8611+
LHSIsTrue = !LHSIsTrue;
8612+
86098613
// Both LHS and RHS are icmps.
86108614
const ICmpInst *LHSCmp = dyn_cast<ICmpInst>(LHS);
86118615
if (LHSCmp)
@@ -8632,10 +8636,21 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
86328636
if (LHS == RHS)
86338637
return LHSIsTrue;
86348638

8635-
if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS))
8636-
return isImpliedCondition(LHS, RHSCmp->getPredicate(),
8637-
RHSCmp->getOperand(0), RHSCmp->getOperand(1), DL,
8638-
LHSIsTrue, Depth);
8639+
// Match not
8640+
bool InvertRHS = false;
8641+
if (match(RHS, m_Not(m_Value(RHS)))) {
8642+
if (LHS == RHS)
8643+
return !LHSIsTrue;
8644+
InvertRHS = true;
8645+
}
8646+
8647+
if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS)) {
8648+
if (auto Implied = isImpliedCondition(
8649+
LHS, RHSCmp->getPredicate(), RHSCmp->getOperand(0),
8650+
RHSCmp->getOperand(1), DL, LHSIsTrue, Depth))
8651+
return InvertRHS ? !*Implied : *Implied;
8652+
return std::nullopt;
8653+
}
86398654

86408655
if (Depth == MaxAnalysisRecursionDepth)
86418656
return std::nullopt;
@@ -8647,21 +8662,21 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
86478662
if (std::optional<bool> Imp =
86488663
isImpliedCondition(LHS, RHS1, DL, LHSIsTrue, Depth + 1))
86498664
if (*Imp == true)
8650-
return true;
8665+
return !InvertRHS;
86518666
if (std::optional<bool> Imp =
86528667
isImpliedCondition(LHS, RHS2, DL, LHSIsTrue, Depth + 1))
86538668
if (*Imp == true)
8654-
return true;
8669+
return !InvertRHS;
86558670
}
86568671
if (match(RHS, m_LogicalAnd(m_Value(RHS1), m_Value(RHS2)))) {
86578672
if (std::optional<bool> Imp =
86588673
isImpliedCondition(LHS, RHS1, DL, LHSIsTrue, Depth + 1))
86598674
if (*Imp == false)
8660-
return false;
8675+
return InvertRHS;
86618676
if (std::optional<bool> Imp =
86628677
isImpliedCondition(LHS, RHS2, DL, LHSIsTrue, Depth + 1))
86638678
if (*Imp == false)
8664-
return false;
8679+
return InvertRHS;
86658680
}
86668681

86678682
return std::nullopt;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
define i1 @test_imply_not1(i32 %depth) {
5+
; CHECK-LABEL: define i1 @test_imply_not1(
6+
; CHECK-SAME: i32 [[DEPTH:%.*]]) {
7+
; CHECK-NEXT: [[CMP1_NOT1:%.*]] = icmp eq i32 [[DEPTH]], 16
8+
; CHECK-NEXT: call void @use(i1 [[CMP1_NOT1]])
9+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[DEPTH]], 8
10+
; CHECK-NEXT: call void @use(i1 [[CMP2]])
11+
; CHECK-NEXT: br i1 [[CMP1_NOT1]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
12+
; CHECK: if.then:
13+
; CHECK-NEXT: call void @func1()
14+
; CHECK-NEXT: unreachable
15+
; CHECK: if.else:
16+
; CHECK-NEXT: call void @func2()
17+
; CHECK-NEXT: unreachable
18+
;
19+
%cmp1 = icmp eq i32 %depth, 16
20+
call void @use(i1 %cmp1)
21+
%cmp2 = icmp slt i32 %depth, 8
22+
call void @use(i1 %cmp2)
23+
%cmp.not = xor i1 %cmp1, true
24+
%brmerge = or i1 %cmp2, %cmp.not
25+
br i1 %brmerge, label %if.then, label %if.else
26+
if.then:
27+
call void @func1()
28+
unreachable
29+
30+
if.else:
31+
call void @func2()
32+
unreachable
33+
}
34+
35+
define i1 @test_imply_not2(i32 %a, i1 %cmp2) {
36+
; CHECK-LABEL: define i1 @test_imply_not2(
37+
; CHECK-SAME: i32 [[A:%.*]], i1 [[CMP2:%.*]]) {
38+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 0
39+
; CHECK-NEXT: [[BRMERGE:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
40+
; CHECK-NEXT: ret i1 [[BRMERGE]]
41+
;
42+
%cmp1 = icmp eq i32 %a, 0
43+
%or.cond = select i1 %cmp1, i1 %cmp2, i1 false
44+
%cmp.not = xor i1 %cmp1, true
45+
%brmerge = or i1 %or.cond, %cmp.not
46+
ret i1 %brmerge
47+
}
48+
49+
define i1 @test_imply_not3(i32 %a, i32 %b, i1 %cond) {
50+
; CHECK-LABEL: define i1 @test_imply_not3(
51+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[COND:%.*]]) {
52+
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], [[B]]
53+
; CHECK-NEXT: call void @use(i1 [[CMP1]])
54+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
55+
; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP2]], i1 [[COND]], i1 false
56+
; CHECK-NEXT: ret i1 [[AND]]
57+
;
58+
%cmp1 = icmp eq i32 %a, %b
59+
call void @use(i1 %cmp1)
60+
%cmp2 = icmp slt i32 %a, %b
61+
%cmp.not = xor i1 %cmp1, true
62+
%sel = select i1 %cmp.not, i1 %cond, i1 false
63+
%and = and i1 %cmp2, %sel
64+
ret i1 %and
65+
}
66+
67+
declare void @func1()
68+
declare void @func2()
69+
declare void @use(i1)

llvm/test/Transforms/LoopVectorize/reduction-inloop.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,9 +1354,8 @@ define i32 @predicated_or_dominates_reduction(ptr %b) {
13541354
; CHECK: pred.load.continue6:
13551355
; CHECK-NEXT: [[TMP43:%.*]] = phi <4 x i32> [ [[TMP37]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP42]], [[PRED_LOAD_IF5]] ]
13561356
; CHECK-NEXT: [[TMP44:%.*]] = icmp ne <4 x i32> [[TMP43]], zeroinitializer
1357-
; CHECK-NEXT: [[TMP45:%.*]] = select <4 x i1> [[TMP19]], <4 x i1> [[TMP44]], <4 x i1> zeroinitializer
13581357
; CHECK-NEXT: [[TMP46:%.*]] = xor <4 x i1> [[TMP19]], <i1 true, i1 true, i1 true, i1 true>
1359-
; CHECK-NEXT: [[TMP47:%.*]] = or <4 x i1> [[TMP45]], [[TMP46]]
1358+
; CHECK-NEXT: [[TMP47:%.*]] = select <4 x i1> [[TMP46]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP44]]
13601359
; CHECK-NEXT: [[TMP48:%.*]] = bitcast <4 x i1> [[TMP47]] to i4
13611360
; CHECK-NEXT: [[TMP49:%.*]] = call i4 @llvm.ctpop.i4(i4 [[TMP48]]), !range [[RNG42:![0-9]+]]
13621361
; CHECK-NEXT: [[TMP50:%.*]] = zext nneg i4 [[TMP49]] to i32

0 commit comments

Comments
 (0)