[PATCH] D140933: [LVI] Look through negations when evaluating conditions
Keno Fischer via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 3 18:02:51 PST 2023
loladiro created this revision.
loladiro added reviewers: nikic, apilipenko.
Herald added a subscriber: hiraditya.
Herald added a project: All.
loladiro requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
This teaches LVI (and thus CVP) to extract range information
from branches whose condition is negated using (`xor %c, true`).
The implementation is relatively straightforward, simply computing
the inverse of the relevant lattice information.
I think the biggest question here is why this negation shows up
here at all. After all, it should always be possible for some
other pass to fold such a negation into a branch, comparison or
some other logical operation. Indeed, instcombine does just that.
However, these negations can be otherwise fairly persistent, e.g.
instsimplify is not able to exchange branch conditions from
negations. In addition, jumpthreading, which sits at the same
point in default pass pipeline also handles this pattern, which
adds further evidence that we might expect these negations to
not have been canonicalized away yet at this point in the pass
pipeline.
In the particular case I was looking at there was a bit of a
circular dependency where flags computed by cvp were needed
by instcombine, and incstombine's folding of the negation was
needed for cvp. Adding a second instombine pass would have
worked of course, but instcombine can be somewhat expensive,
so it appeared desirable to not require it to have run
before cvp (as is the case in the default pass pipeline).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D140933
Files:
llvm/lib/Analysis/LazyValueInfo.cpp
llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
Index: llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
===================================================================
--- llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -1853,6 +1853,28 @@
ret void
}
+define i1 @xor_neg_cond(i32 %a) {
+; CHECK-LABEL: @xor_neg_cond(
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
+; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], true
+; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
+; CHECK: guard:
+; CHECK-NEXT: ret i1 true
+; CHECK: exit:
+; CHECK-NEXT: ret i1 false
+;
+ %cmp1 = icmp eq i32 %a, 10
+ %xor = xor i1 %cmp1, true
+ br i1 %xor, label %exit, label %guard
+
+guard:
+ %cmp2 = icmp eq i32 %a, 10
+ ret i1 %cmp2
+
+exit:
+ ret i1 false
+}
+
declare i32 @llvm.uadd.sat.i32(i32, i32)
declare i32 @llvm.usub.sat.i32(i32, i32)
declare i32 @llvm.sadd.sat.i32(i32, i32)
Index: llvm/lib/Analysis/LazyValueInfo.cpp
===================================================================
--- llvm/lib/Analysis/LazyValueInfo.cpp
+++ llvm/lib/Analysis/LazyValueInfo.cpp
@@ -129,6 +129,21 @@
B.isConstantRangeIncludingUndef());
}
+static ValueLatticeElement inverse(const ValueLatticeElement &A)
+{
+ if (A.isUnknown() || A.isUndef() || A.isOverdefined())
+ return A;
+
+ if (A.isConstant())
+ return ValueLatticeElement::getNot(A.getConstant());
+
+ if (A.isNotConstant())
+ return ValueLatticeElement::get(A.getNotConstant());
+
+ ConstantRange Range = A.getConstantRange().inverse();
+ return ValueLatticeElement::getRange(Range, A.isConstantRangeIncludingUndef());
+}
+
//===----------------------------------------------------------------------===//
// LazyValueInfoCache Decl
//===----------------------------------------------------------------------===//
@@ -1181,6 +1196,16 @@
return getValueFromOverflowCondition(Val, WO, isTrueDest);
}
+ Value *N;
+ if (match(Cond, m_Not(m_Value(N)))) {
+ auto NV = Visited.find(N);
+ if (NV == Visited.end()) {
+ Worklist.push_back(N);
+ return std::nullopt;
+ }
+ return inverse(NV->second);
+ }
+
Value *L, *R;
bool IsAnd;
if (match(Cond, m_LogicalAnd(m_Value(L), m_Value(R))))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140933.486127.patch
Type: text/x-patch
Size: 2337 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230104/2f9bafc6/attachment.bin>
More information about the llvm-commits
mailing list