Skip to content

Commit 0fb9981

Browse files
committed
[optnone] Make the optnone attribute effective at suppressing function
attribute and function argument attribute synthesizing and propagating. As with the other uses of this attribute, the goal remains a best-effort (no guarantees) attempt to not optimize the function or assume things about the function when optimizing. This is particularly useful for compiler testing, bisecting miscompiles, triaging things, etc. I was hitting specific issues using optnone to isolate test code from a test driver for my fuzz testing, and this is one step of fixing that. llvm-svn: 215538
1 parent 1013b6b commit 0fb9981

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

llvm/lib/Transforms/IPO/FunctionAttrs.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
161161
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
162162
Function *F = (*I)->getFunction();
163163

164-
if (!F)
165-
// External node - may write memory. Just give up.
164+
if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
165+
// External node or node we don't want to optimize - assume it may write
166+
// memory and give up.
166167
return false;
167168

168169
AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F);
@@ -527,7 +528,8 @@ bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) {
527528
// looking up whether a given CallGraphNode is in this SCC.
528529
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
529530
Function *F = (*I)->getFunction();
530-
if (F && !F->isDeclaration() && !F->mayBeOverridden())
531+
if (F && !F->isDeclaration() && !F->mayBeOverridden() &&
532+
!F->hasFnAttribute(Attribute::OptimizeNone))
531533
SCCNodes.insert(F);
532534
}
533535

@@ -541,8 +543,9 @@ bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) {
541543
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
542544
Function *F = (*I)->getFunction();
543545

544-
if (!F)
545-
// External node - only a problem for arguments that we pass to it.
546+
if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
547+
// External node or function we're trying not to optimize - only a problem
548+
// for arguments that we pass to it.
546549
continue;
547550

548551
// Definitions with weak linkage may be overridden at linktime with
@@ -794,8 +797,8 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
794797
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
795798
Function *F = (*I)->getFunction();
796799

797-
if (!F)
798-
// External node - skip it;
800+
if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
801+
// External node or node we don't want to optimize - skip it;
799802
return false;
800803

801804
// Already noalias.
@@ -834,6 +837,9 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
834837
/// given function and set any applicable attributes. Returns true
835838
/// if any attributes were set and false otherwise.
836839
bool FunctionAttrs::inferPrototypeAttributes(Function &F) {
840+
if (F.hasFnAttribute(Attribute::OptimizeNone))
841+
return false;
842+
837843
FunctionType *FTy = F.getFunctionType();
838844
LibFunc::Func TheLibFunc;
839845
if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc)))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: opt < %s -functionattrs -S | FileCheck %s
2+
3+
@x = global i32 0
4+
5+
define void @test_opt(i8* %p) {
6+
; CHECK-LABEL: @test_opt
7+
; CHECK: (i8* nocapture readnone %p) #0 {
8+
ret void
9+
}
10+
11+
define void @test_optnone(i8* %p) noinline optnone {
12+
; CHECK-LABEL: @test_optnone
13+
; CHECK: (i8* %p) #1 {
14+
ret void
15+
}
16+
17+
declare i8 @strlen(i8*) noinline optnone
18+
; CHECK-LABEL: @strlen
19+
; CHECK: (i8*) #1
20+
21+
; CHECK-LABEL: attributes #0
22+
; CHECK: = { readnone }
23+
; CHECK-LABEL: attributes #1
24+
; CHECK: = { noinline optnone }

0 commit comments

Comments
 (0)