[llvm-dev] Question: llvm-link type merge behaviour of c++ classes

Björn Fiedler via llvm-dev llvm-dev at lists.llvm.org
Thu May 28 03:33:22 PDT 2020


Hi LLVM community,

I'd like to ask a question regarding the behavior of llvm-link:

My code contains Classes which are structurally equivalent but they are totally unrelated and distinct on a c++ point of view.
However, if the compiled IR gets processed by llvm-link, these types are merged together.
My question is: Is this expected behavior or a bug?

To explain it more in detail, a reduced example follows:

IR code before llvm-link:
```
...
%class.Bakery = type { i32, i32 }
%class.Container = type { i8 }
%class.Rectangle = type <{ %class.Shape, i8, [3 x i8] }>
%class.Shape = type { i32, i32 }
...
define linkonce_odr dso_local void @_ZN9Container6insertEP5Shape(%class.Container*, %class.Shape*) #1 comdat align 2 { ... }
...
```

IR code after llvm-link:
```
...
%class.Bakery = type { i32, i32 }
%class.Container = type { i8 }
%class.Rectangle = type <{ %class.Bakery, i8, [3 x i8] }>
...
define linkonce_odr dso_local void @_ZN9Container6insertEP5Shape(%class.Container*, %class.Bakery*) #1 comdat align 2 { ... }
...
```

In this example the `Bakery` and `Shape` types get merged. The type definition of `Rectangle` reflects this change, too, but from my intuition, they should stay distinct. I've fond an article from Chris[1] where the new type system is described. There he states that the name gets part of the type. "This means that LLVM 3.0 doesn't exhibit the previous confusing behavior where two seemingly different structs would be printed with the same name."

So, if the name is part of the type and the "confusing behavior" is removed, why get these types merged? Is this the intended behavior?

My use-case and reason for all this comes from writing an analysis tool for IR code which gets stuck in finding matching calls for function pointers. The changing and merging in these types messes up the current logic of finding matching candidates.

To reproduce this code, find the c++ code below and use the following invocations:
```
clang++-9 mwe.cc -S -emit-llvm -o before_link.ll
llvm-link-9 -S before_link.ll -o after_link.ll
```

mwe.cc
```
// #include "shapes.h"
// shapes.h content follows
class Shape {
  public:
    int width, height;
};

class Rectangle : public Shape {
  public:
    bool is_square;
};

class Container {
  public:
    void insert(Shape* s){};
};

// end shapes.h

// #include "bakery.h"
// bakery.h content follows:
class Bakery {
  public:
    int num_ovens, num_employees;
};
// end bakery.h

// some instances
Bakery b;

Container c;
Rectangle r;

void do_stuff() { c.insert(&r); }

void bake(Bakery* bakery) {}
```

My system:
```
clang++-9 --version
clang version 9.0.1-12
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin


llvm-link-9 --version
LLVM (http://llvm.org/):
  LLVM version 9.0.1
 
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: skylake
```


Thanks in advance
Björn


[1] http://blog.llvm.org/2011/11/llvm-30-type-system-rewrite.html


-- 
Björn Fiedler, M.Sc. (Scientific Staff)
Leibniz Universität Hannover (LUH)
Fachgebiet System- und Rechnerarchitektur (SRA)
Appelstraße 4
30167 Hannover, Germany

Tel:    +49 511 762-19736
Fax:    +49 511 762-19733
eMail:  fiedler at sra.uni-hannover.de
WWW:    https://www.sra.uni-hannover.de


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200528/237c6f23/attachment.sig>


More information about the llvm-dev mailing list