From ca857efb5b7308d5dda621685a766da6960a8157 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Tue, 15 Sep 2015 17:51:50 +0000 Subject: [PATCH] [CorrelatedValuePropagation] Infer nonnull attributes LazuValueInfo can prove that value is nonnull based on the context information. Make use of this ability to infer nonnull attributes for the call arguments. Differential Revision: http://reviews.llvm.org/D12836 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247707 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/CorrelatedValuePropagation.cpp | 31 +++++++++++++++ .../CorrelatedValuePropagation/non-null.ll | 39 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 8706dfee73d..ac12427015d 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -44,6 +44,7 @@ namespace { bool processMemAccess(Instruction *I); bool processCmp(CmpInst *C); bool processSwitch(SwitchInst *SI); + bool processCallSite(CallSite CS); public: static char ID; @@ -309,6 +310,32 @@ bool CorrelatedValuePropagation::processSwitch(SwitchInst *SI) { return Changed; } +/// processCallSite - Infer nonnull attributes for the arguments at the +/// specified callsite. +bool CorrelatedValuePropagation::processCallSite(CallSite CS) { + bool Changed = false; + + unsigned ArgNo = 0; + for (Value *V : CS.args()) { + PointerType *Type = dyn_cast(V->getType()); + + if (Type && !CS.paramHasAttr(ArgNo + 1, Attribute::NonNull) && + LVI->getPredicateAt(ICmpInst::ICMP_EQ, V, + ConstantPointerNull::get(Type), + CS.getInstruction()) == LazyValueInfo::False) { + AttributeSet AS = CS.getAttributes(); + AS = AS.addAttribute(CS.getInstruction()->getContext(), ArgNo + 1, + Attribute::NonNull); + CS.setAttributes(AS); + Changed = true; + } + ArgNo++; + } + assert(ArgNo == CS.arg_size() && "sanity check"); + + return Changed; +} + bool CorrelatedValuePropagation::runOnFunction(Function &F) { if (skipOptnoneFunction(F)) return false; @@ -336,6 +363,10 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) { case Instruction::Store: BBChanged |= processMemAccess(II); break; + case Instruction::Call: + case Instruction::Invoke: + BBChanged |= processCallSite(CallSite(II)); + break; } } diff --git a/test/Transforms/CorrelatedValuePropagation/non-null.ll b/test/Transforms/CorrelatedValuePropagation/non-null.ll index 6bb8bb07c45..a24dfb67ca1 100644 --- a/test/Transforms/CorrelatedValuePropagation/non-null.ll +++ b/test/Transforms/CorrelatedValuePropagation/non-null.ll @@ -101,3 +101,42 @@ bb: ; CHECK: KEEP2 ret void } + +declare void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) +define void @test10(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) { +; CHECK-LABEL: @test10 +entry: + %is_null = icmp eq i8* %arg1, null + br i1 %is_null, label %null, label %non_null + +non_null: + call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) + ; CHECK: call void @test10_helper(i8* nonnull %arg1, i8* %arg2, i32 %non-pointer-arg) + br label %null + +null: + call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) + ; CHECK: call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) + ret void +} + +declare void @test11_helper(i8* %arg) +define void @test11(i8* %arg1, i8** %arg2) { +; CHECK-LABEL: @test11 +entry: + %is_null = icmp eq i8* %arg1, null + br i1 %is_null, label %null, label %non_null + +non_null: + br label %merge + +null: + %another_arg = alloca i8 + br label %merge + +merge: + %merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null] + call void @test11_helper(i8* %merged_arg) + ; CHECK: call void @test11_helper(i8* nonnull %merged_arg) + ret void +} -- 2.34.1