[PATCH] D109194: [InstCombine] Optimize (a & b) | (~a & c)

Matthias Braun via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 10 16:15:21 PDT 2021


MatzeB added a comment.

> do we know if many backends match this pattern as well as the more common (a & b) | (~a & c) to their bit select instructions (bsl/pcmov/etc.)?

I tried `llc` with the following test:

  define i32 @variant0(i32, i32, i32) {
    %4 = and i32 %1, %0
    %5 = xor i32 %0, -1
    %6 = and i32 %5, %2
    %7 = or i32 %6, %4
    ret i32 %7
  }
  
  define i32 @variant1(i32, i32, i32) {
    %4 = xor i32 %2, %1
    %5 = and i32 %4, %0
    %6 = xor i32 %5, %2
    ret i32 %6
  }

(generic) X86: variant0 produces "mov; and; not; and; or"

  variant1 produces "mov; xor; and; xor"

X86 -mattr=+bmi: variant0 and variant1 produce "and, andn, orl"
AArch64: variant0 and variant1 produce "bix, and, orr"
ARM: variant0 produces "and; bic; orr"

  variant1 produces "eor; and; eor"

ppc32: variant0/variant1 produce the same code: "and; andc; or"
ppc64: variant0 produces "and; xori; xoris; and; or"?!?

  variant1 produces "andc; and; or" which is clearly better

riscv32/riscv64: variant0 produces "and; not; and; or"

  variant1 produces "xor; and; xor"

> Targets without and "and-not" instruction variant1 seems better and this patch will help produce better code there. Most targets with an "and-not" use it either way, except for ARM which fails to recognize the xor variant and PPC64 which fails to recognize the and-not variant...
=========================================================================================================================================================================================================================================================================================


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109194/new/

https://reviews.llvm.org/D109194



More information about the llvm-commits mailing list