[llvm-dev] "Unusual" linkage inhibits interprocedural constant propagation?

Alex P. via llvm-dev llvm-dev at lists.llvm.org
Sun Oct 25 13:24:31 PDT 2020


Hi Johannes, thanks for reply. I suspected that ipconstprop was not 
active in -O3 mode, but I did not know it was deprecated at all. 
However, either -O3 or -ipsccp behave the same way.

BTW what other inter-procedural deductions should not apply for _odr 
linkage? As far as I understand, an _odr definition is quite similar to 
an extern definition semantically (well, according to C++'s definition 
of ODR rule)...

On 25-Oct-20 12:08 PM, Johannes Doerfert wrote:
> Hi Alex,
> 
> this is a "bug", as far as I can tell.
> 
> `_odr` linkage should allow inter-procedural propagation of constant 
> returns,
> though prevent other inter-procedural deductions. This is why we are a bit
> cautious with these things.
> 
> I won't fix ipconstprop because we actually removed it but I will look 
> into an
> extension of the Attributor to allow this. IPSCCP can probably also be 
> taught to
> do this.
> 
> ~ Johannes
> 
> 
> On 10/23/20 10:40 PM, Alex P. via llvm-dev wrote:
>> Dear LLVM developers and adopters!
>>
>> $ cat ipcp-1.ll
>> define
>> ;linkonce_odr
>> dso_local i32 @f() noinline {
>>    ret i32 123
>> }
>> define dso_local i32 @g()
>> {
>>    %res = call i32 @f()
>>    ret i32 %res
>> }
>> $ opt-10 -S -ipconstprop ipcp-1.ll
>> ; ModuleID = 'ipcp-1.ll'
>> source_filename = "ipcp-1.ll"
>>
>> ; Function Attrs: noinline
>> define dso_local i32 @f() #0 {
>>   ret i32 123
>> }
>>
>> define dso_local i32 @g() {
>>   %res = call i32 @f()
>>   ret i32 123 <========== note the result
>> }
>>
>> attributes #0 = { noinline }
>>
>> BUT:
>>
>> $ cat ipcp-2.ll
>> define
>> linkonce_odr
>> dso_local i32 @f() noinline {
>>    ret i32 123
>> }
>> define dso_local i32 @g()
>> {
>>    %res = call i32 @f()
>>    ret i32 %res
>> }
>> $ opt-10 -S -ipconstprop ipcp-2.ll
>> ; ModuleID = 'ipcp-2.ll'
>> source_filename = "ipcp-2.ll"
>>
>> ; Function Attrs: noinline
>> define linkonce_odr dso_local i32 @f() #0 {
>>   ret i32 123
>> }
>>
>> define dso_local i32 @g() {
>>   %res = call i32 @f()
>>   ret i32 %res <========== note the (lack of) result
>> }
>>
>> attributes #0 = { noinline }
>>
>> WHY? It this a bug?
>>
>> I observe the same behavior if I replace "-ipconstprop" with "-O3" or 
>> replace "linkonce_odr" with "available_externally", and if I use an 
>> equivalent testcase in C++ (compiled with the clang++ frontend). No 
>> problem with "external", "private" or "hidden" linkages. Also note 
>> that those "linkonce_odr"/"available_externally" do not inhibit, e.g., 
>> inlining (if I remove "noinline"), that is, as implied from the IR 
>> documentation.
>>
>> I am using LLVM version 10.0.0.
>>
>> This is a showstopper for my project (actually trying to use LLVM as 
>> an affordable static type inferer for a dynamically typed PL).
>>
>> Thanks for any help

-- 
Alex <alex at webprise.net>


More information about the llvm-dev mailing list