Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIMD] code not recognized as all_true #50142

Open
llvmbot opened this issue Jun 22, 2021 · 4 comments
Open

[SIMD] code not recognized as all_true #50142

llvmbot opened this issue Jun 22, 2021 · 4 comments
Labels
backend:WebAssembly bugzilla Issues migrated from bugzilla confirmed Verified by a second party openmp

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 22, 2021

Bugzilla Link 50798
Version trunk
OS Windows NT
Reporter LLVM Bugzilla Contributor
CC @rotateright,@tlively

Extended Description

LLVM doesn't recognize that it can optimize these functions to an *.all_true instruction.. This one might be a bit too specialized; it doesn't surprise me at all that LLVM doesn't generate an *.all_true instruction. Still, it would be nice since the scalar version is pretty bad.

I've included an OpenMP SIMD annotation to try to help the compiler, but obviously it would be better if it weren't required.

Here is the example, or on Compiler Explorer at https://godbolt.org/z/x3xshzYrf if you prefer:

#include <stdint.h>

#pragma clang diagnostic ignored "-Wmissing-prototypes"

/* Because of <#45959 >, not
 * a WASM issue. */
#pragma clang diagnostic ignored "-Wsign-conversion"

typedef int8_t i8x16 __attribute__((__vector_size__(16)));
typedef int16_t i16x8 __attribute__((__vector_size__(16)));
typedef int32_t i32x4 __attribute__((__vector_size__(16)));
typedef int64_t i64x2 __attribute__((__vector_size__(16)));

int
i8x16_all_true(i8x16 a) {
    int8_t r = ~0;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 16 ; i++) {
        r &= a[i];
    }
    return !!r;
}

int
i8x16_all_true_intrin(i8x16 a) {
    return __builtin_wasm_all_true_i8x16(a);
}

int
i16x8_all_true(i16x8 a) {
    int16_t r = ~0;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 8 ; i++) {
        r &= a[i];
    }
    return !!r;
}

int
i16x8_all_true_intrin(i16x8 a) {
    return __builtin_wasm_all_true_i16x8(a);
}

int
i32x4_all_true(i32x4 a) {
    int32_t r = ~0;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 4 ; i++) {
        r &= a[i];
    }
    return !!r;
}

int
i32x4_all_true_intrin(i32x4 a) {
    return __builtin_wasm_all_true_i32x4(a);
}

int
i64x2_all_true(i64x2 a) {
    int64_t r = ~0;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 2 ; i++) {
        r &= a[i];
    }
    return !!r;
}

int
i64x2_all_true_intrin(i64x2 a) {
    return __builtin_wasm_all_true_i64x2(a);
}
@llvmbot
Copy link
Collaborator Author

llvmbot commented Jun 22, 2021

Sorry, copied from the wrong tab, here is a corrected test (Compiler Explorer: https://godbolt.org/z/ref5rf19z):

#include <stdint.h>

#pragma clang diagnostic ignored "-Wmissing-prototypes"

/* Because of <#45959 >, not
 * a WASM issue. */
#pragma clang diagnostic ignored "-Wsign-conversion"

typedef int8_t i8x16 __attribute__((__vector_size__(16)));
typedef int16_t i16x8 __attribute__((__vector_size__(16)));
typedef int32_t i32x4 __attribute__((__vector_size__(16)));
typedef int64_t i64x2 __attribute__((__vector_size__(16)));

int
i8x16_all_true(i8x16 a) {
    int8_t r = 1;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 16 ; i++) {
        r &= !!a[i];
    }
    return r;
}

int
i8x16_all_true_intrin(i8x16 a) {
    return __builtin_wasm_all_true_i8x16(a);
}

int
i16x8_all_true(i16x8 a) {
    int16_t r = 1;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 8 ; i++) {
        r &= !!a[i];
    }
    return r;
}

int
i16x8_all_true_intrin(i16x8 a) {
    return __builtin_wasm_all_true_i16x8(a);
}

int
i32x4_all_true(i32x4 a) {
    int32_t r = 1;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 4 ; i++) {
        r &= !!a[i];
    }
    return r;
}

int
i32x4_all_true_intrin(i32x4 a) {
    return __builtin_wasm_all_true_i32x4(a);
}

int
i64x2_all_true(i64x2 a) {
    int64_t r = 1;
    #pragma omp simd reduction(&:r)
    for (int i = 0 ; i < 2 ; i++) {
        r &= !!a[i];
    }
    return r;
}

int
i64x2_all_true_intrin(i64x2 a) {
    return __builtin_wasm_all_true_i64x2(a);
}

@tlively
Copy link
Collaborator

tlively commented Jul 30, 2021

This one is going to be a bit trickier than llvm/llvm-bugzilla-archive#50796 because I don't believe there is an existing reduction intrinsic corresponding to this operation.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@llvmbot llvmbot added the confirmed Verified by a second party label Jan 26, 2022
@mr-c
Copy link

mr-c commented Nov 6, 2023

I can confirm that this issue still exists in clang version 18.0.0 (https://github.com/llvm/llvm-project.git cf7d4f5) using the provided Compiler Explorer link: https://godbolt.org/z/ref5rf19z

@Endilll Endilll added the openmp label Nov 6, 2023
@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 6, 2023

@llvm/issue-subscribers-openmp

Author: None (llvmbot)

| | | | --- | --- | | Bugzilla Link | [50798](https://llvm.org/bz50798) | | Version | trunk | | OS | Windows NT | | Reporter | LLVM Bugzilla Contributor | | CC | @rotateright,@tlively |

Extended Description

LLVM doesn't recognize that it can optimize these functions to an *.all_true instruction.. This one might be a bit too specialized; it doesn't surprise me at all that LLVM doesn't generate an *.all_true instruction. Still, it would be nice since the scalar version is pretty bad.

I've included an OpenMP SIMD annotation to try to help the compiler, but obviously it would be better if it weren't required.

Here is the example, or on Compiler Explorer at https://godbolt.org/z/x3xshzYrf if you prefer:

#include <stdint.h>

#pragma clang diagnostic ignored "-Wmissing-prototypes"

/* Because of <#45959 >, not

  • a WASM issue. */
    #pragma clang diagnostic ignored "-Wsign-conversion"

typedef int8_t i8x16 attribute((vector_size(16)));
typedef int16_t i16x8 attribute((vector_size(16)));
typedef int32_t i32x4 attribute((vector_size(16)));
typedef int64_t i64x2 attribute((vector_size(16)));

int
i8x16_all_true(i8x16 a) {
int8_t r = ~0;
#pragma omp simd reduction(&:r)
for (int i = 0 ; i < 16 ; i++) {
r &= a[i];
}
return !!r;
}

int
i8x16_all_true_intrin(i8x16 a) {
return __builtin_wasm_all_true_i8x16(a);
}

int
i16x8_all_true(i16x8 a) {
int16_t r = ~0;
#pragma omp simd reduction(&:r)
for (int i = 0 ; i < 8 ; i++) {
r &= a[i];
}
return !!r;
}

int
i16x8_all_true_intrin(i16x8 a) {
return __builtin_wasm_all_true_i16x8(a);
}

int
i32x4_all_true(i32x4 a) {
int32_t r = ~0;
#pragma omp simd reduction(&:r)
for (int i = 0 ; i < 4 ; i++) {
r &= a[i];
}
return !!r;
}

int
i32x4_all_true_intrin(i32x4 a) {
return __builtin_wasm_all_true_i32x4(a);
}

int
i64x2_all_true(i64x2 a) {
int64_t r = ~0;
#pragma omp simd reduction(&:r)
for (int i = 0 ; i < 2 ; i++) {
r &= a[i];
}
return !!r;
}

int
i64x2_all_true_intrin(i64x2 a) {
return __builtin_wasm_all_true_i64x2(a);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:WebAssembly bugzilla Issues migrated from bugzilla confirmed Verified by a second party openmp
Projects
None yet
Development

No branches or pull requests

4 participants