Bug 26545 reports that the "noinline" attribute does not prevent the result of a function to be "inlined" into the caller.
The problem comes in fact from the Inter-Procedural Sparse Constant Propagation which propagates the return value into the caller.
This patch fixes this problem by patching the function "canTrackReturnsInterprocedurally". This function now returns false on functions with the "noinline" attribute.
Test case:
llvm/test/Transforms/IPConstantProp/noinline.ll
; RUN: opt -ipsccp -S %s | FileCheck %s
define internal fastcc i32 @v1() #0 {
entry:
ret i32 1
; No IPSCCP when noinline attribute
; CHECK: ret i32 1
}
define internal fastcc i32 @v2() {
entry:
ret i32 2
; IPSCCP on this function
; CHECK: ret i32 undef
}
define internal fastcc i32 @foo(i32 %x, i32 %y) {
entry:
%add = add nsw i32 %y, %x %call = tail call fastcc i32 @v1() %add1 = add nsw i32 %add, %call %call2 = tail call fastcc i32 @v2() %add3 = add nsw i32 %add1, %call2 ret i32 %add3
; CHECK: ret i32 %add3
}
define i32 @bar() {
entry:
%call = tail call fastcc i32 @v1() %call1 = tail call fastcc i32 @v2() %call2 = tail call fastcc i32 @foo(i32 %call, i32 %call1) ret i32 %call2
; CHECK ret i32 %call2
}
attributes #0 = { noinline }