Skip to content

Commit 657f26f

Browse files
committed
[SCCP] Add more non-null roots
Also consider allocas non-null (subject to the usual caveats), and consider nonnull/dereferenceable metadata on calls.
1 parent 3250305 commit 657f26f

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
673673
void visitStoreInst(StoreInst &I);
674674
void visitLoadInst(LoadInst &I);
675675
void visitGetElementPtrInst(GetElementPtrInst &I);
676+
void visitAllocaInst(AllocaInst &AI);
676677

677678
void visitInvokeInst(InvokeInst &II) {
678679
visitCallBase(II);
@@ -1626,6 +1627,13 @@ void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
16261627
markConstant(&I, C);
16271628
}
16281629

1630+
void SCCPInstVisitor::visitAllocaInst(AllocaInst &I) {
1631+
if (!NullPointerIsDefined(I.getFunction(), I.getAddressSpace()))
1632+
return (void)markNotNull(ValueState[&I], &I);
1633+
1634+
markOverdefined(&I);
1635+
}
1636+
16291637
void SCCPInstVisitor::visitStoreInst(StoreInst &SI) {
16301638
// If this store is of a struct, ignore it.
16311639
if (SI.getOperand(0)->getType()->isStructTy())
@@ -1647,18 +1655,23 @@ void SCCPInstVisitor::visitStoreInst(StoreInst &SI) {
16471655
}
16481656

16491657
static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
1650-
if (I->getType()->isIntOrIntVectorTy()) {
1651-
if (MDNode *Ranges = I->getMetadata(LLVMContext::MD_range))
1652-
return ValueLatticeElement::getRange(
1653-
getConstantRangeFromMetadata(*Ranges));
1654-
1655-
if (const auto *CB = dyn_cast<CallBase>(I))
1658+
if (const auto *CB = dyn_cast<CallBase>(I)) {
1659+
if (CB->getType()->isIntOrIntVectorTy())
16561660
if (std::optional<ConstantRange> Range = CB->getRange())
16571661
return ValueLatticeElement::getRange(*Range);
1662+
if (CB->getType()->isPointerTy() && CB->isReturnNonNull())
1663+
return ValueLatticeElement::getNot(
1664+
ConstantPointerNull::get(cast<PointerType>(I->getType())));
16581665
}
1666+
1667+
if (I->getType()->isIntOrIntVectorTy())
1668+
if (MDNode *Ranges = I->getMetadata(LLVMContext::MD_range))
1669+
return ValueLatticeElement::getRange(
1670+
getConstantRangeFromMetadata(*Ranges));
16591671
if (I->hasMetadata(LLVMContext::MD_nonnull))
16601672
return ValueLatticeElement::getNot(
16611673
ConstantPointerNull::get(cast<PointerType>(I->getType())));
1674+
16621675
return ValueLatticeElement::getOverdefined();
16631676
}
16641677

llvm/test/Transforms/SCCP/pointer-nonnull.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ define i1 @test_dereferenceable(ptr dereferenceable(4) %p) {
4343
define i1 @test_alloca() {
4444
; CHECK-LABEL: define i1 @test_alloca() {
4545
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
46-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[A]], null
47-
; CHECK-NEXT: ret i1 [[CMP]]
46+
; CHECK-NEXT: ret i1 true
4847
;
4948
%a = alloca i32
5049
%cmp = icmp ne ptr %a, null
@@ -88,8 +87,7 @@ define i1 @test_load_nonnull(ptr %p) {
8887
define i1 @test_call_nonnull() {
8988
; CHECK-LABEL: define i1 @test_call_nonnull() {
9089
; CHECK-NEXT: [[P:%.*]] = call nonnull ptr @get()
91-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P]], null
92-
; CHECK-NEXT: ret i1 [[CMP]]
90+
; CHECK-NEXT: ret i1 true
9391
;
9492
%p = call nonnull ptr @get()
9593
%cmp = icmp ne ptr %p, null
@@ -99,8 +97,7 @@ define i1 @test_call_nonnull() {
9997
define i1 @test_call_dereferenceable() {
10098
; CHECK-LABEL: define i1 @test_call_dereferenceable() {
10199
; CHECK-NEXT: [[P:%.*]] = call dereferenceable(4) ptr @get()
102-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P]], null
103-
; CHECK-NEXT: ret i1 [[CMP]]
100+
; CHECK-NEXT: ret i1 true
104101
;
105102
%p = call dereferenceable(4) ptr @get()
106103
%cmp = icmp ne ptr %p, null

0 commit comments

Comments
 (0)