llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.59k stars 11.35k forks source link

generate x86 `pext` from general code #98217

Open ImpleLee opened 1 month ago

ImpleLee commented 1 month ago

I want to use x86-64 pext, but I also want my function to look platform-agnostic, so I don't want to use intrinsics or inline assembly. I tried some semantic-equivalent implementations of pext I found online, but none of them can be compiled to pext. Is it really possible to make the compiler generate the pext instruction? Or will there be any plan to support this behavior?

Here are the pext implementations I tried. ( https://godbolt.org/z/f3vMTf8ob )

// from https://stackoverflow.com/questions/21144237
int pext1(int x, int mask) {
  int res = 0;
  for(int bb = 1; mask != 0; bb += bb) {
    if(x & mask & -mask) {
      res |= bb;
    }
    mask &= (mask - 1);
  }
  return res;
}

// from https://www.felixcloutier.com/x86/pext
int pext2(int x, int mask) {
  int res = 0;
  int k = 0;
  for (int m = 0; m < 32; ++m) {
    if (mask & (1 << m)) {
        res |= ((x >> m) & 1) << k;
        k += 1;
    }
  }
  return res;
}
llvmbot commented 1 month ago

@llvm/issue-subscribers-backend-x86

Author: Imple Lee (ImpleLee)

I want to use x86-64 `pext`, but I also want my function to look platform-agnostic, so I don't want to use intrinsics or inline assembly. I tried some semantic-equivalent implementations of `pext` I found online, but none of them can be compiled to `pext`. Is it really possible to make the compiler generate the `pext` instruction? Or will there be any plan to support this behavior? Here are the `pext` implementations I tried. ( https://godbolt.org/z/f3vMTf8ob ) ```c++ // from https://stackoverflow.com/questions/21144237 int pext1(int x, int mask) { int res = 0; for(int bb = 1; mask != 0; bb += bb) { if(x & mask & -mask) { res |= bb; } mask &= (mask - 1); } return res; } // from https://www.felixcloutier.com/x86/pext int pext2(int x, int mask) { int res = 0; int k = 0; for (int m = 0; m < 32; ++m) { if (mask & (1 << m)) { res |= ((x >> m) & 1) << k; k += 1; } } return res; } ```
topperc commented 1 month ago

It is not currently possible to generate pext from anything other than intrinsics or inline assembly.

ImpleLee commented 1 month ago

It is not currently possible to generate pext from anything other than intrinsics or inline assembly.

Thank you for your reply. Should I close this issue or leave it as a to-do for general pext generation? I am OK with both options.

RKSimon commented 1 month ago

Not exactly the same, but discourse has discussed making generic pdep/pext intrinsics in the past: https://discourse.llvm.org/t/how-would-i-go-about-implementing-new-bit-manipulation-builtins-for-my-proposal-especially-generic-builtins/76523