In the provided test case, DAG combiner fails to recognize and combine `(srl
(shl, i8:c0), i64:c1)` even though c0 == c1 in value (but exist as separate
SDNodes because of their different value types). The solution then is to compare
by value rather than node ID.
Note that InstCombine (and thus, opt) fails to combine this as well.
This was discovered with the following bit of C:
C
#include <stdint.h>
typedef struct {
uint32_t low;
uint32_t high;
} pair;
pair cmpxchg8b(uint64_t *m, pair src) {
pair rv = {0, 0};
asm volatile("cmpxchg8b %2"
: "+a"(rv.low), "+d"(rv.high), "+m"(m)
: "b"(src.low), "c"(src.high)
: "flags");
return rv;
}
unsigned f(uint64_t *m, unsigned a, unsigned b) {
pair p = {a > 0, b > 0};
pair rv = cmpxchg8b(m, p);
return rv.low != 0 && rv.high > 0;
}for which clang generates:
f:
pushq %rbx
testl %esi, %esi
setne %al
testl %edx, %edx
setne %cl
movzbl %al, %ebx
movzbl %cl, %ecx
movq %rdi, -8(%rsp)
xorl %edx, %edx
xorl %eax, %eax
#APP
cmpxchg8b -8(%rsp)
#NO_APP
testl %eax, %eax
setne %al
movl %edx, %ecx # <======
testq %rcx, %rcx
setne %cl
andb %al, %cl
movzbl %cl, %eax
popq %rbx
retq
Please regenerate the patch with context - something like