<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css">body { background: rgba(255, 255, 255, 255); }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hello,<br class=""><br class="">I noticed recently that the code gen of <font face="Courier" class="">CanType::getClassOrBoundGenericClass()</font> 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.<div class=""><br class=""></div><div class="">When more than one <font face="Courier" class="">dyn_cast()</font> 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:</div><div class=""><br class=""></div><div class=""><font face="Courier" class=""><+35>: movb 0x8(%rbx), %cl ; getKind()<br class=""><b class=""><+38>: testq %rbx, %rbx ; XXX - nullptr check after deref is pointless<br class=""></b><+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=""><b class=""><+56>: testq %rbx, %rbx ; XXX - another pointless nullptr check?<br class=""></b><+59>: je 0x1377e09 ; <+73><br class=""><+61>: cmpb $0x29, %cl ; isa<BoundGenericClassType>()<br class=""><+64>: jne 0x1377e09 ; <+73><br class=""><+66>: addq $0x18, %rbx </font><span style="font-family: Courier;" class="">; </span><span style="font-family: Courier;" class="">(void*)</span><span style="font-family: Courier;" class="">this + offsetof(</span><span style="font-family: Courier;" class="">BoundGenericClassType</span><span style="font-family: Courier;" class="">, TheDecl)</span></div><div class=""><font face="Courier" class=""><+70>: movq (%rbx), %rax ; load the decl pointer</font></div><div class=""><font face="Courier" class=""><+73>: popq %rbx<br class=""><+74>: retq <br class=""></font><br class=""></div><div 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 “<font face="Courier" class="">const TypeBase *</font>” parameter and then have<font face="Courier" class=""> CanType::getClassOrBoundGenericClass()</font> call that.</div><div class=""><br class=""></div><div class="">FWIW – I *suspect* this is because LLVM’s casting machinery internally converts traditional pointers into C++ references before ultimately calling <font face="Courier" class="">classof(&Val)</font>.</div><div class=""><br class=""></div><div class="">Before I file a bug against clang/llvm, might I be missing something? Can anybody think of a good workaround?</div><div class=""><br class=""></div><div class="">Dave</div></body></html>