<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class="">I don’t have the IR handy. You can easily generate it for yourself though. Just drop the following into any file (I use swift/lib/AST/Type.cpp) and recompile swift.</div><div class=""><br class=""></div><div class=""><font face="Courier" class="">Decl *my_test_function(Type t) {</font></div><div class=""><font face="Courier" class=""> return t->getClassOrBoundGenericClass();</font></div><div class=""><font face="Courier" class="">}<br class=""></font><div class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 1, 2018, at 12:53, Michael Gottesman <<a href="mailto:mgottesman@apple.com" class="">mgottesman@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Do you have the llvm-ir handy?<br class=""><br class=""><blockquote type="cite" class="">On Jan 1, 2018, at 11:30 AM, David Zarzycki via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:<br class=""><br class="">Hello,<br class=""><br class="">I noticed recently that the code gen of CanType::getClassOrBoundGenericClass() could be better and along the way I found a clang/LLVM bug. Where exactly, I do not know, although my bet is the LLVM optimizer.<br class=""><br class="">When more than one dyn_cast() happens in a row, LLVM/clang emits redundant and pointless nullptr checks. Both Apple clang-900.0.39.2 and clang/llvm top-of-tree generate essentially the same code:<br class=""><br class=""><+35>: movb 0x8(%rbx), %cl ; getKind()<br class=""><+38>: testq %rbx, %rbx ; XXX - nullptr check after deref is pointless<br class=""><+41>: je 0x1377df6 ; <+54><br class=""><+43>: cmpb $0x12, %cl ; isa<ClassType>()<br class=""><+46>: jne 0x1377df6 ; <+54><br class=""><+48>: addq $0x10, %rbx ; (void*)this + offsetof(ClassType, TheDecl)<br class=""><+52>: jmp 0x1377e06 ; <+70><br class=""><+54>: xorl %eax, %eax ; the default return value (nullptr)<br class=""><+56>: testq %rbx, %rbx ; XXX - another pointless nullptr check?<br class=""><+59>: je 0x1377e09 ; <+73><br class=""><+61>: cmpb $0x29, %cl ; isa<BoundGenericClassType>()<br class=""><+64>: jne 0x1377e09 ; <+73><br class=""><+66>: addq $0x18, %rbx ; (void*)this + offsetof(BoundGenericClassType, TheDecl)<br class=""><+70>: movq (%rbx), %rax ; load the decl pointer<br class=""><+73>: popq %rbx<br class=""><+74>: retq <br class=""><br class="">I’ve tried adding different “nonnull” spellings in various parts of both Swift and LLVM’s casting machinery, but with no luck. The only thing that seems to work is to create a free function that takes a non-null “const TypeBase *” parameter and then have CanType::getClassOrBoundGenericClass() call that.<br class=""><br class="">FWIW – I *suspect* this is because LLVM’s casting machinery internally converts traditional pointers into C++ references before ultimately calling classof(&Val).<br class=""><br class="">Before I file a bug against clang/llvm, might I be missing something? Can anybody think of a good workaround?<br class=""><br class="">Dave<br class="">_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-dev<br class=""></blockquote><br class=""></div></div></blockquote></div><br class=""></div></div></div></body></html>