llvm / llvm-project

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

nontemporal instructions not generated for #pragma omp simd nontemporal #55757

Open shivaramaarao opened 2 years ago

shivaramaarao commented 2 years ago

For the following program, compiler is expected to generate nontemporal instructions

void test(int *ArrayPt, int *Pointer, int n)
{
#pragma omp simd nontemporal(ArrayPt,Pointer)
  for (int i=0;i<n;i++) {
     *ArrayPt += *Pointer;
     ArrayPt++;
     Pointer++;
   }
}

Yes, the non-temporal instructions are generated at O0 (on x86 platform).

used the option : clang -fopenmp <test.c>

        movntiq %rax, -8(%rbp)
        movq    -16(%rbp), %rax
        addq    $4, %rax
        movntiq %rax, -16(%rbp)

At O1 and above, the non-temporal hint seem to be ignored and the non-temporal instructions are not getting generated.

        movdqu  %xmm2, (%rdi,%rcx,4)
        movdqu  %xmm0, 16(%rdi,%rcx,4)

Is it expected behavior?. I think the nontemporal metadata is not getting propagated incase of optimizations. The meta data seem to get dropped at SROA pass.

RKSimon commented 2 years ago

This can occur if the vector type isn't aligned - does it work if you specifiy 16 byte alignment for the pointers?

efriedma-quic commented 2 years ago

As far as I can tell, LLVM optimizations are doing the right thing here. The accesses to the local variables ArrayPt and Pointer are marked non-temporal, so they get emitted that way at -O0. At higher optimization levels, SROA eliminates those variables.

I think clang is misintepreting the OpenMP standard here. The directive nontemporal(ArrayPt,Pointer) is supposed to be mean that array accesses through the pointers ArrayPt and Pointer should be non-temporal. But clang is interpreting it to mean that accesses to the variables themselves are supposed to be non-temporal. Granted, the standard is badly worded; it doesn't explicitly say that operands to nontemporal directives have to be pointers, so maybe clang's current interpretation could be justified.

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-codegen

llvmbot commented 2 years ago

@llvm/issue-subscribers-openmp

jdoerfert commented 2 years ago

I think we interpret the standard wrong and should mark the accesses via those pointers as nontemporal.

DominikAdamski commented 2 years ago

Do we agree that Clang is misinterpreting OpenMP standard and we should mark all the accesses via those pointers as nontemporal?

I am planning to add support for simd nontemporal clause to OMPIRBuilder and I would like to clarify the proper behavior of simd nontemporal pragma.

shiltian commented 1 year ago

@DominikAdamski Is the issue still around?