[llvm-dev] devirtualization with new-PM pipeline

Fedor Sergeev via llvm-dev llvm-dev at lists.llvm.org
Thu Dec 7 12:09:52 PST 2017


Chandler et al,

I have been playing with the new PM pipeline, being particularly 
interested in how it can handle devirtualization.
Now, I discovered what I believe is a "regression" vs old PM on a rather 
simple one-translation-unit testcase.

clang is able to devirtualize it with -O3 and fails to do so with 
-fexperimental-new-pass-manager added.

It looks like a pipeline issue, though I did not dig deeper as I'm not 
sure if this kind of behavior
is expected at current stage of New PM life or not?

If it is not expected then I'ld be happy to file a bug and do a bit 
deeper look for the cause.

regards,
   Fedor.
-------------------------------
] cat devirt.cpp
struct A {
   virtual int virt1();
};
struct B : A {
   int virt1() override {
     return 20;
   }
};
static int redirect(A* a) {
   return a->virt1();
}
int calc() {
   B b;
   return redirect(&b);
}
] clang++ -O3 devirt.cpp -std=c++11 -S -emit-llvm -o -
...
define i32 @_Z4calcv() local_unnamed_addr #0 {
entry:
   ret i32 20    <--- nicely devirtualized (&b)->virt1() call
}
...
] clang++ -O3 -fexperimental-new-pass-manager -std=c++11 -S -emit-llvm -o -
...
define i32 @_Z4calcv() local_unnamed_addr #0 {
entry:
   %b = alloca %struct.B, align 8
   %0 = bitcast %struct.B* %b to i8*
   call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #3
   %1 = getelementptr inbounds %struct.B, %struct.B* %b, i64 0, i32 0, i32 0
   store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] 
}, { [3 x i8*] }* @_ZTV1B, i64 0, inrange i32 0, i64 2) to i32 (...)**), 
i32 (...)*** %1, align 8, !tbaa !2
   %call.i = call i32 @_ZN1B5virt1Ev(%struct.B* nonnull %b)
   call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #3
   ret i32 %call.i
}
...
] clang++ --version
clang version 6.0.0 (trunk 319748) (llvm/trunk 319768)
Target: x86_64-unknown-linux-gnu
Thread model: posix




More information about the llvm-dev mailing list