-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Labels
Description
CGP's sinkCmpExpression is duplicating a costly CmpInst in multiple blocks instead of just reusing the result
using Word = unsigned _BitInt(128);
void doit(const Word &a, const Word &b, Word *p0, Word *p1) {
bool eq = a == b;
*p0++ |= Word((unsigned)eq);
if (eq) {
*p1++ |= Word((unsigned)eq);
}
}define void @doit(ptr %a, ptr %b, ptr %p0, ptr %p1) {
entry:
%0 = load i128, ptr %a, align 8
%1 = load i128, ptr %b, align 8
%cmp = icmp eq i128 %0, %1
%conv1 = zext i1 %cmp to i128
%2 = load i128, ptr %p0, align 8
%or = or i128 %2, %conv1
store i128 %or, ptr %p0, align 8
br i1 %cmp, label %if.then, label %if.end
if.then:
%3 = load i128, ptr %p1, align 8
%or7 = or i128 %3, %conv1
store i128 %or7, ptr %p1, align 8
br label %if.end
if.end:
ret void
}doit:
# %bb.0: # %entry
movq (%rdi), %rax
movq 8(%rdi), %r8
vmovdqu (%rdi), %xmm0
movq (%rsi), %r9
movq 8(%rsi), %rdi
vpxor (%rsi), %xmm0, %xmm0
xorl %esi, %esi
vptest %xmm0, %xmm0 ; FIRST COMPARISON
sete %sil
orq %rsi, (%rdx)
vptest %xmm0, %xmm0 ; SECOND COMPARISON - use TEST ESI,ESI?
jne .LBB0_2
# %bb.1: # %if.then
xorq %r9, %rax
xorq %rdi, %r8
xorl %edx, %edx
orq %rax, %r8 ; THIRD COMPARISON - ARGH!
sete %dl
orq %rdx, (%rcx)
.LBB0_2: # %if.end
retqThe third comparison in particular is annoying as we can no longer fold to a VPTEST as the i128 are split into i64 pairs.
It looks like some targets have already started overriding TLI::hasMultipleConditionRegisters to hack this - we might just want to do the same on x86.