https://llvm.org/bugs/show_bug.cgi?id=26067
Bug ID: 26067 Summary: Unable to de-abstract std::tuple comparisons Product: libraries Version: 3.7 Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P Component: Scalar Optimizations Assignee: unassignedb...@nondot.org Reporter: chisophu...@gmail.com CC: llvm-bugs@lists.llvm.org Classification: Unclassified Consider this case, where lexicographical comparison of bit fields is equivalent to a direct integer comparison of the `Data` field: #include <stdint.h> #include <tuple> struct A { uint32_t Data; std::tuple<int, int, int> getAsTuple() const { return std::make_tuple((Data & 0xFFFF0000) >> 16, (Data & 0xFF00) >> 8, (Data & 0xFF)); } }; bool cmp_eq(A LHS, A RHS) { return LHS.getAsTuple() == RHS.getAsTuple(); } bool cmp_lt(A LHS, A RHS) { return LHS.getAsTuple() < RHS.getAsTuple(); } This produces the following assembly with clang 3.7: cmp_eq(A, A): # @cmp_eq(A, A) cmpl %edi, %esi sete %al retq cmp_lt(A, A): # @cmp_lt(A, A) movl %esi, %ecx movl %edi, %edx movl %edx, %esi shrl $16, %esi movl %ecx, %edi shrl $16, %edi movb $1, %al cmpl %edi, %esi jb .LBB1_5 cmpl %esi, %edi jae .LBB1_3 xorl %eax, %eax retq .LBB1_3: movzbl %dh, %esi # NOREX movzbl %ch, %edi # NOREX cmpl %edi, %esi jb .LBB1_5 movzbl %dl, %eax movzbl %cl, %ecx cmpl %ecx, %eax sbbb %cl, %cl cmpl %esi, %edi setae %al andb %cl, %al .LBB1_5: # %bool std::operator< <int, int, int, int, int, int>(std::tuple<int, int, int> const&, std::tuple<int, int, int> const&) [clone .exit] retq (cmp_eq is substantially improved from clang 3.6 btw. Play around here: https://goo.gl/RVJeGa ) Clang 3.7 gets cmp_eq "right". But cmp_lt is far from optimal (it should be the same as cmp_eq but choosing a different condition code). This pattern just cropped up for me in the wild on some non-LLVM code that I was working on. Using std::make_tuple/std::tie to synthesize lexicographical comparisons dramatically simplifies code, so I expect this sort of situation with adjacent bit fields to crop up in the wild as a byproduct (I don't know how much it has caught on, but it likely will catch on if it hasn't). In LLVM, we are using std::make_tuple/std::tie for lexicographical comparisons pretty extensively (e.g. r202755). At least in this case one can uglify the code to get the right codegen (just manually compare the `Data` field), but in the bitfield case I don't think there's even a well-defined way to get the right codegen https://goo.gl/sCLraB -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs