[llvm-dev] Debugging a potential bug when generating wasm32

Ömer Sinan Ağacan via llvm-dev llvm-dev at lists.llvm.org
Tue Aug 4 21:05:45 PDT 2020


Hi,

Sorry if you've seen this message before on llvm.discourse.group or elsewhere --
I've been trying to get to the bottom of this for a while now and asked about
this in a few different platforms before.

I'm currently trying to debug a bug in a LLVM-generated Wasm code. The bug could
be in the code that generates LLVM (rustc) or in the LLVM, I'm not sure yet.
LLVM IR and Wasm can be seen in [1].

The problem is this line:

    (import "GOT.func"
"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"
(global (;3;) (mut i32)))

The same symbol is already imported from "env" in the same module:

    (import "env"
"_ZN5core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"
(func (;4;) (type 1)))

So there's no need to import it from "GOT.func" and I want to get rid of that
"GOT.func" import.

This LLVM IR is generated when compiling Rust code to a "staticlib", which is
supposed to include *all* dependencies of the code so that it'll be linkable
with code for other languages. Because of the "GOT.func" import this module is
not linkable, it needs to resolve that "GOT.func" import in runtime using
dynamic linking for Wasm [2].

I'm trying to understand whether this is a rustc bug or an LLVM bug. I'm using
LLVM 10 downloaded from the official web page and rustc nightly. I can build
LLVM from source and use it, but I don't have any experience in LLVM code base.
Questions:

- Given a reference to a symbol, how does LLVM decide how to import it?
  Currently I see these uses of the problematic symbol in LLVM IR:

  - `store i8* bitcast (i1 (i32*, %"core::fmt::Formatter"*)*
@"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"
to i8*), i8** %11, align 4`

  - `store i8* bitcast (i1 (i32*, %"core::fmt::Formatter"*)*
@"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"
to i8*), i8** %14, align 4`

  - `store i8* bitcast (i1 (i32*, %"core::fmt::Formatter"*)*
@"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"
to i8*), i8** %17, align 4`

  - `declare zeroext i1
@"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h9ba9fea9cadf7bd5E"(i32*
noalias readonly align 4 dereferenceable(4), %"core::fmt::Formatter"*
align 4 dereferenceable(36)) unnamed_addr #1`

  First three look very similar so I'm guessing the first three are causing one
  of those imports, and the last one is causing the other import, but I'm not
  sure which one is generating which import. Any ideas?

- Any suggestions on how to debug this? Just knowing which line in the LLVM IR
  listed above causes this "GOT.func" import would be helpful.

Thanks,

Ömer

[1]: https://gist.github.com/osa1/4c672fe8998c8e8768cf9f7c014c61d8
[2]: https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md


More information about the llvm-dev mailing list