Skip to content

[X86] Unnecessary repeated costly comparisons in multiple blocks #166534

@RKSimon

Description

@RKSimon

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
        retq

The 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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions