Alex P. via llvm-dev
2020-Oct-24 03:40 UTC
[llvm-dev] "Unusual" linkage inhibits interprocedural constant propagation?
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>
Johannes Doerfert via llvm-dev
2020-Oct-25 17:08 UTC
[llvm-dev] "Unusual" linkage inhibits interprocedural constant propagation?
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 P. via llvm-dev
2020-Oct-25 20:24 UTC
[llvm-dev] "Unusual" linkage inhibits interprocedural constant propagation?
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>