Index: lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- lib/Transforms/IPO/FunctionAttrs.cpp +++ lib/Transforms/IPO/FunctionAttrs.cpp @@ -44,6 +44,12 @@ STATISTIC(NumNoAlias, "Number of function returns marked noalias"); STATISTIC(NumAnnotated, "Number of attributes added to library functions"); +static cl::opt ReadAttrsAnalysisUsesThreshold( + "readattrs-analysis-uses-threshold", cl::Hidden, cl::init(20), + cl::ZeroOrMore, + cl::desc("Control the maximum number of uses to analyze for " + "readonly/readnone attribute (default = 20)")); + namespace { struct FunctionAttrs : public CallGraphSCCPass { static char ID; // Pass identification, replacement for typeid @@ -425,7 +431,7 @@ // We don't need to track IsWritten. If A is written to, return immediately. for (Use &U : A->uses()) { - if (Count++ >= 20) + if (Count++ >= ReadAttrsAnalysisUsesThreshold) return Attribute::None; Visited.insert(&U); Index: test/Transforms/FunctionAttrs/readattrs-threshold.ll =================================================================== --- /dev/null +++ test/Transforms/FunctionAttrs/readattrs-threshold.ll @@ -0,0 +1,13 @@ +; RUN: opt < %s -functionattrs -S | FileCheck %s --check-prefix=CHECK +; RUN: opt < %s -functionattrs -readattrs-analysis-uses-threshold=1 -S | FileCheck %s --check-prefix=CHECK-NO-READATTR + +; %p has two uses +; CHECK: define i32 @test(i32* nocapture readonly %p) +; CHECK-NO-READATTR: define i32 @test(i32* nocapture %p) +define i32 @test(i32* %p) { + %1 = load i32, i32* %p + %2 = getelementptr i32, i32* %p, i32 1 + %3 = load i32, i32* %2 + %4 = add i32 %1, %3 + ret i32 %4 +}