> On Jan 1, 2018, at 18:20, John McCall <rjmcc...@apple.com> wrote: > >> >> On Jan 1, 2018, at 5:51 PM, David Zarzycki via swift-dev >> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >> >> Hi Michael, >> >> I reduced it down to a simple test case. I was wrong about this requiring >> two or more dyn_casts. This actually affects any C++ code that uses the “if >> (auto x = y(z))” convention. What follows is the reduction (compiled with >> “clang++ -O3 -c” if it matters): >> >> // Uncomment the next line to see the expected code gen (albeit not inlined) >> //__attribute__((used,noinline)) >> int *x(void *arg) { >> return ((long long)arg & 1) ? (int *)arg : nullptr; >> } >> >> int test(void *arg) { >> if (auto y = x(arg)) >> return *y; >> return 42; >> } >> >> It seems like inlining ‘x’ causes the compiler to effectively generate the >> following pseudo-code: >> >> int test(void *arg) { >> if (arg != nullptr) >> if (arg & 1) >> return *arg; >> return 42; >> } >> >> Which is surprising in multiple ways and (as far as I can tell) difficult to >> workaround without lots of source churn. >> >> Where should I file a bug? > > bugs.llvm.org <http://bugs.llvm.org/> would be best. Including both your > reduced test case and the fact that it was reduced from dyn_cast patterns > should make them sit up and take notice.
Thanks John, In case anybody wants to cherry-pick the fix once it is found: https://bugs.llvm.org/show_bug.cgi?id=35790 > John. > >> >> Dave >> >> >>> On Jan 1, 2018, at 13:10, David Zarzycki via swift-dev <swift-dev@swift.org >>> <mailto:swift-dev@swift.org>> wrote: >>> >>> 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. >>> >>> Decl *my_test_function(Type t) { >>> return t->getClassOrBoundGenericClass(); >>> } >>> >>> >>>> On Jan 1, 2018, at 12:53, Michael Gottesman <mgottes...@apple.com >>>> <mailto:mgottes...@apple.com>> wrote: >>>> >>>> Do you have the llvm-ir handy? >>>> >>>>> On Jan 1, 2018, at 11:30 AM, David Zarzycki via swift-dev >>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >>>>> >>>>> Hello, >>>>> >>>>> 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. >>>>> >>>>> 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: >>>>> >>>>> <+35>: movb 0x8(%rbx), %cl ; getKind() >>>>> <+38>: testq %rbx, %rbx ; XXX - nullptr check after deref is >>>>> pointless >>>>> <+41>: je 0x1377df6 ; <+54> >>>>> <+43>: cmpb $0x12, %cl ; isa<ClassType>() >>>>> <+46>: jne 0x1377df6 ; <+54> >>>>> <+48>: addq $0x10, %rbx ; (void*)this + offsetof(ClassType, TheDecl) >>>>> <+52>: jmp 0x1377e06 ; <+70> >>>>> <+54>: xorl %eax, %eax ; the default return value (nullptr) >>>>> <+56>: testq %rbx, %rbx ; XXX - another pointless nullptr check? >>>>> <+59>: je 0x1377e09 ; <+73> >>>>> <+61>: cmpb $0x29, %cl ; isa<BoundGenericClassType>() >>>>> <+64>: jne 0x1377e09 ; <+73> >>>>> <+66>: addq $0x18, %rbx ; (void*)this + >>>>> offsetof(BoundGenericClassType, TheDecl) >>>>> <+70>: movq (%rbx), %rax ; load the decl pointer >>>>> <+73>: popq %rbx >>>>> <+74>: retq >>>>> >>>>> 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. >>>>> >>>>> FWIW – I *suspect* this is because LLVM’s casting machinery internally >>>>> converts traditional pointers into C++ references before ultimately >>>>> calling classof(&Val). >>>>> >>>>> Before I file a bug against clang/llvm, might I be missing something? Can >>>>> anybody think of a good workaround? >>>>> >>>>> Dave >>>>> _______________________________________________ >>>>> swift-dev mailing list >>>>> swift-dev@swift.org <mailto:swift-dev@swift.org> >>>>> https://lists.swift.org/mailman/listinfo/swift-dev >>>>> <https://lists.swift.org/mailman/listinfo/swift-dev> >>>> >>> >>> _______________________________________________ >>> swift-dev mailing list >>> swift-dev@swift.org <mailto:swift-dev@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-dev >>> <https://lists.swift.org/mailman/listinfo/swift-dev> >> >> _______________________________________________ >> swift-dev mailing list >> swift-dev@swift.org <mailto:swift-dev@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-dev >> <https://lists.swift.org/mailman/listinfo/swift-dev>
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev