[LLVMbugs] [Bug 9641] New: Missing optimization for dynamic_cast to/from final class

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Apr 7 08:07:41 PDT 2011


http://llvm.org/bugs/show_bug.cgi?id=9641

           Summary: Missing optimization for dynamic_cast to/from final
                    class
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++0x
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: richard-llvm at metafoo.co.uk
                CC: llvmbugs at cs.uiuc.edu, dgregor at apple.com


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.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list