-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Closed
Labels
bugzillaIssues migrated from bugzillaIssues migrated from bugzillac++11llvm:optimizationsmissed-optimization
Description
| Bugzilla Link | 9641 |
| Version | trunk |
| OS | Linux |
| CC | @DougGregor |
Extended Description
Consider this:
class A { virtual ~A(); };
class B final : public A {};
extern struct A *p;
int main() {
return dynamic_cast<B*>(p) != 0;
}This produces the following IR:
; ModuleID = '-'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
%0 = type { i8*, i8*, i8* }
%class.A = type { i32 (...)** }
%class.B = type { [8 x i8] }
@​p = external global %class.A*
@​_ZTI1A = external constant i8*
@​_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
@​_ZTS1B = linkonce_odr constant [3 x i8] c"1B\00"
@​_ZTI1B = linkonce_odr unnamed_addr constant %0 { i8* bitcast (i8** getelementptr inbounds (i8** @​_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @​_ZTS1B, i32 0, i32 0), i8* bitcast (i8** @​_ZTI1A to i8*) }
define i32 @​main() nounwind {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval
%tmp = load %class.A** @​p, align 8
%0 = icmp ne %class.A* %tmp, null
br i1 %0, label %1, label %5
; <label>:1 ; preds = %entry
%2 = bitcast %class.A* %tmp to i8*
%3 = call i8* @​__dynamic_cast(i8* %2, i8* bitcast (i8** @​_ZTI1A to i8*), i8* bitcast (%0* @​_ZTI1B to i8*), i64 -1)
%4 = bitcast i8* %3 to %class.B*
br label %6
; <label>:5 ; preds = %entry
br label %6
; <label>:6 ; preds = %5, %1
%7 = phi %class.B* [ %4, %1 ], [ null, %5 ]
%cmp = icmp ne %class.B* %7, null
%conv = zext i1 %cmp to i32
ret i32 %conv
}
declare i8* @​__dynamic_cast(i8*, i8*, i8*, i64)
Since 'B' is final, the call to __dynamic_cast is unnecessary: we can just directly compare p's vptr against B's vptr.
When dynamic_cast<>ing /from/ a final type, the situation is even better: all dynamic_cast<>s can be directly resolved at compile time.
Metadata
Metadata
Assignees
Labels
bugzillaIssues migrated from bugzillaIssues migrated from bugzillac++11llvm:optimizationsmissed-optimization