[PATCH] D27491: [LVI] Meet rules for non-null pointers
Philip Reames via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 6 16:29:23 PST 2016
reames created this revision.
reames added reviewers: nicholas, apilipenko, igmyrj, sanjoy, jmolloy.
reames added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.
The patch itself is fairly straight-forward, it simply extends LVI conservative meet operator to remember non-null facts when merging non-null constants.
However, the fact I had to write this is really making me question the value of pointer types in LVI as a whole. The lack of any decent meet rule basically means that pointer handling in LVI reduces to equality propagation and a dereferenceability based non-null analysis. Given GVN implements a version of the former (minus the meet of two constants case), I'm wondering whether pointers should just be removed from LVI and handled separately. I want to stew on that a bit further before actually landing this patch.
https://reviews.llvm.org/D27491
Files:
lib/Analysis/LazyValueInfo.cpp
test/Transforms/CorrelatedValuePropagation/select.ll
Index: test/Transforms/CorrelatedValuePropagation/select.ll
===================================================================
--- test/Transforms/CorrelatedValuePropagation/select.ll
+++ test/Transforms/CorrelatedValuePropagation/select.ll
@@ -216,3 +216,53 @@
; CHECK: ret i1 true
ret i1 true
}
+
+define i1 @test7(i1 %unknown, i32* nonnull %p1, i32* nonnull %p2 ) {
+; CHECK-LABEL: @test7
+ %sel = select i1 %unknown, i32* %p1, i32* %p2
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 true
+ %res = icmp ne i32* %sel, null
+ ret i1 %res
+}
+ at g1 = external global i32
+ at g2 = external global i32
+
+define i1 @test8a(i1 %unknown, i32* nonnull %p1) {
+; CHECK-LABEL: @test8
+ %sel = select i1 %unknown, i32* %p1, i32* @g1
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 true
+ %res = icmp ne i32* %sel, null
+ ret i1 %res
+}
+
+define i1 @test8b(i1 %unknown, i32* nonnull %p1) {
+; CHECK-LABEL: @test8
+ %sel = select i1 %unknown, i32* %p1, i32* @g1
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 true
+ %res = icmp ne i32* %sel, null
+ ret i1 %res
+}
+
+define i1 @test9(i1 %unknown) {
+; CHECK-LABEL: @test9
+ %sel = select i1 %unknown, i32* @g1, i32* @g2
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 true
+ %res = icmp ne i32* %sel, null
+ ret i1 %res
+}
Index: lib/Analysis/LazyValueInfo.cpp
===================================================================
--- lib/Analysis/LazyValueInfo.cpp
+++ lib/Analysis/LazyValueInfo.cpp
@@ -222,12 +222,22 @@
if (RHS.isConstant()) {
if (Val == RHS.Val)
return false;
+
+ PointerType *PT = dyn_cast<PointerType>(Val->getType());
+ if (PT && isKnownNonNull(Val) && isKnownNonNull(RHS.Val))
+ return markNotConstant(ConstantPointerNull::get(PT));
+
return markOverdefined();
}
if (RHS.isNotConstant()) {
if (Val == RHS.Val)
return markOverdefined();
+
+ PointerType *PT = dyn_cast<PointerType>(Val->getType());
+ if (PT && isa<ConstantPointerNull>(RHS.Val) && isKnownNonNull(Val))
+ return markNotConstant(ConstantPointerNull::get(PT));
+
return markOverdefined();
}
@@ -238,6 +248,11 @@
if (RHS.isConstant()) {
if (Val == RHS.Val)
return markOverdefined();
+
+ PointerType *PT = dyn_cast<PointerType>(Val->getType());
+ if (PT && isa<ConstantPointerNull>(Val) && isKnownNonNull(RHS.Val))
+ return false;
+
return markOverdefined();
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27491.80501.patch
Type: text/x-patch
Size: 2837 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161207/2d740344/attachment.bin>
More information about the llvm-commits
mailing list