<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&nbsp;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>&nbsp;happens in a row, LLVM/clang emits redundant and pointless nullptr checks. Both&nbsp;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="">&lt;+35&gt;: movb &nbsp; 0x8(%rbx), %cl &nbsp;; getKind()<br class=""><b class="">&lt;+38&gt;: testq &nbsp;%rbx, %rbx &nbsp; &nbsp; &nbsp;; XXX - nullptr check after deref is pointless<br class=""></b>&lt;+41&gt;: je &nbsp; &nbsp; 0x1377df6 &nbsp; &nbsp; &nbsp; ; &lt;+54&gt;<br class="">&lt;+43&gt;: cmpb &nbsp; $0x12, %cl &nbsp; &nbsp; &nbsp;; isa&lt;ClassType&gt;()<br class="">&lt;+46&gt;: jne &nbsp; &nbsp;0x1377df6 &nbsp; &nbsp; &nbsp; ; &lt;+54&gt;<br class="">&lt;+48&gt;: addq &nbsp; $0x10, %rbx &nbsp; &nbsp; ; (void*)this + offsetof(ClassType, TheDecl)<br class="">&lt;+52&gt;: jmp &nbsp; &nbsp;0x1377e06 &nbsp; &nbsp; &nbsp; ; &lt;+70&gt;<br class="">&lt;+54&gt;: xorl &nbsp; %eax, %eax &nbsp; &nbsp; &nbsp;; the default return value (nullptr)<br class=""><b class="">&lt;+56&gt;: testq &nbsp;%rbx, %rbx &nbsp; &nbsp; &nbsp;; XXX - another pointless nullptr check?<br class=""></b>&lt;+59&gt;: je &nbsp; &nbsp; 0x1377e09 &nbsp; &nbsp; &nbsp; ; &lt;+73&gt;<br class="">&lt;+61&gt;: cmpb &nbsp; $0x29, %cl &nbsp; &nbsp; &nbsp;; isa&lt;BoundGenericClassType&gt;()<br class="">&lt;+64&gt;: jne &nbsp; &nbsp;0x1377e09 &nbsp; &nbsp; &nbsp; ; &lt;+73&gt;<br class="">&lt;+66&gt;: addq &nbsp; $0x18, %rbx &nbsp; &nbsp;&nbsp;</font><span style="font-family: Courier;" class="">;&nbsp;</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="">&lt;+70&gt;: movq &nbsp; (%rbx), %rax &nbsp; &nbsp;; load the decl pointer</font></div><div class=""><font face="Courier" class="">&lt;+73&gt;: popq &nbsp; %rbx<br class="">&lt;+74&gt;: retq&nbsp; &nbsp;<br class=""></font><br class=""></div><div class="">I’ve tried adding different “nonnull” spellings&nbsp;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(&amp;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>