AuburnSounds / intel-intrinsics

The Dlang SIMD library
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#techs=MMX,SSE,SSE2,SSE3,SSSE3,SSE4_1
Boost Software License 1.0
68 stars 11 forks source link

__mm256_srl_epi64() returns different results on LDC when -mattr=+avx2 is on #143

Open apbryan opened 1 month ago

apbryan commented 1 month ago

The following code fails on my machine when compiling (ldc) with -mattr=+avx2

unittest                                                                                                                     
{                                                                                                                            
    import inteli.avx2intrin;                                                                                                
    import std.stdio;                                                                                                        

    long4 start = [0xffff_ffff_0000_0000,                                                                                    
                    0xffff_ffff_0000_0000,                                                                                   
                    0xffff_ffff_0000_0000,                                                                                   
                    0xffff_ffff_0000_0000];                                                                                  
    int4 shift = [32,0,0,0];                                                                                                 
    long4 res = _mm256_srl_epi64(start, shift);                                                                              
    long4 expected = [0x0000_0000_ffff_ffff,                                                                                 
                      0x0000_0000_ffff_ffff,                                                                                 
                      0x0000_0000_ffff_ffff,                                                                                 
                      0x0000_0000_ffff_ffff];                                                                                
    writefln!"%(0x%08x %)"(res.array);                                                                                       
    assert(res.array == expected.array);                                                                                     
}

When NOT building with -mattr=+avx2:

alex@compy  xxhash-d/trunk dub test --compiler=ldc2 --force -v                                                        22:14:30 24-08-12
Note: Failed to determine version of package xxhash-d at .. Assuming ~master.
Scanning local packages...
  Found dependency intel-intrinsics 1.11.19
             Generating test runner configuration 'xxhash-d-test-library' for 'library' (library).
Get module name from path: /home/alex/programming/xxhash-d/trunk/source/xxhash.d
Get module name from path: /home/alex/programming/xxhash-d/trunk/source/xxhash3.d
Configuring dependent xxhash-d, deps:"intel-intrinsics"
  Configuring dependent intel-intrinsics, deps:
    Starting Performing "unittest" build using ldc2 for x86_64.
    Building intel-intrinsics 1.11.19: building configuration [library]
ldc2 -d-debug -g -w --oq -od=/home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/obj -d-version=Have_intel_intrinsics -I../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/avx2intrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/avxintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/bmi2intrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/emmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/internals.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/math.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/mmx.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/nmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/package.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/pmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/shaintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/smmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/tmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/types.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/xmmintrin.d -lib -of/home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a -vcolumns
Copying target from /home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a to /home/alex/.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics
    Building xxhash-d ~master: building configuration [xxhash-d-test-library]
ldc2 -d-debug -g -unittest -w --oq -od=/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-ivhtjaULboegsICHPTxUEQ/obj -d-version=Have_xxhash_d -d-version=Have_intel_intrinsics -Isource/ -I../../../.dub/cache/xxhash-d/~master/code/xxhash-d-test-library-unittest-_BNJh3iyL7ewM_mTcxPsSQ -I../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source ../../../.dub/cache/xxhash-d/~master/code/xxhash-d-test-library-unittest-_BNJh3iyL7ewM_mTcxPsSQ/dub_test_root.d source/xxhash.d source/xxhash3.d -preview=in -preview=dip1000 -preview=dip1008 -c -of/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-ivhtjaULboegsICHPTxUEQ/xxhash-d-test-library.o -vcolumns
     Linking xxhash-d-test-library
ldc2 -of/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-ivhtjaULboegsICHPTxUEQ/xxhash-d-test-library /home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-ivhtjaULboegsICHPTxUEQ/xxhash-d-test-library.o ../../../.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a -L--no-as-needed -g
Copying target from /home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-ivhtjaULboegsICHPTxUEQ/xxhash-d-test-library to /home/alex/programming/xxhash-d/trunk
     Running xxhash-d-test-library 
0xffffffff 0xffffffff 0xffffffff 0xffffffff
1 modules passed unittests

When building with -mattr=+avx2:

alex@compy  xxhash-d/trunk dub test --compiler=ldc2 --force -v                                                        22:17:35 24-08-12
Note: Failed to determine version of package xxhash-d at .. Assuming ~master.
Scanning local packages...
  Found dependency intel-intrinsics 1.11.19
             Generating test runner configuration 'xxhash-d-test-library' for 'library' (library).
Get module name from path: /home/alex/programming/xxhash-d/trunk/source/xxhash.d
Get module name from path: /home/alex/programming/xxhash-d/trunk/source/xxhash3.d
Configuring dependent xxhash-d, deps:"intel-intrinsics"
  Configuring dependent intel-intrinsics, deps:
    Starting Performing "unittest" build using ldc2 for x86_64.
    Building intel-intrinsics 1.11.19: building configuration [library]
ldc2 -d-debug -g -w --oq -od=/home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/obj -d-version=Have_intel_intrinsics -I../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/avx2intrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/avxintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/bmi2intrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/emmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/internals.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/math.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/mmx.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/nmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/package.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/pmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/shaintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/smmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/tmmintrin.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/types.d ../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source/inteli/xmmintrin.d -lib -of/home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a -vcolumns
Copying target from /home/alex/.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a to /home/alex/.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics
    Building xxhash-d ~master: building configuration [xxhash-d-test-library]
ldc2 -d-debug -g -unittest -w --oq -od=/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-IwBIdhnKYnjHStNI3AjrCg/obj -d-version=Have_xxhash_d -d-version=Have_intel_intrinsics -Isource/ -I../../../.dub/cache/xxhash-d/~master/code/xxhash-d-test-library-unittest-_BNJh3iyL7ewM_mTcxPsSQ -I../../../.dub/packages/intel-intrinsics/1.11.19/intel-intrinsics/source ../../../.dub/cache/xxhash-d/~master/code/xxhash-d-test-library-unittest-_BNJh3iyL7ewM_mTcxPsSQ/dub_test_root.d source/xxhash.d source/xxhash3.d -preview=in -preview=dip1000 -preview=dip1008 mattr=+avx2 -c -of/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-IwBIdhnKYnjHStNI3AjrCg/xxhash-d-test-library.o -vcolumns
     Linking xxhash-d-test-library
ldc2 -of/home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-IwBIdhnKYnjHStNI3AjrCg/xxhash-d-test-library /home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-IwBIdhnKYnjHStNI3AjrCg/xxhash-d-test-library.o ../../../.dub/cache/intel-intrinsics/1.11.19/build/library-unittest-pN-lT8bZKhbU81suGMOpGA/libintel-intrinsics.a -L--no-as-needed -g
Copying target from /home/alex/.dub/cache/xxhash-d/~master/build/xxhash-d-test-library-unittest-IwBIdhnKYnjHStNI3AjrCg/xxhash-d-test-library to /home/alex/programming/xxhash-d/trunk
     Running xxhash-d-test-library 
0x00000000 0x00000000 0xffffffff00000000 0xffffffff00000000
core.exception.AssertError@source/xxhash3.d(1340): Assertion failure
----------------
??:? _d_assert [0x7efd3b3f0792]
source/xxhash3.d:1340 [0x556289fc256d]
source/xxhash3.d [0x556289fe1caf]
??:? [0x7efd3b413445]
??:? [0x7efd3b43153a]
??:? int rt.sections_elf_shared.DSO.opApply(scope int delegate(ref rt.sections_elf_shared.DSO)) [0x7efd3b4325c8]
??:? int rt.minfo.moduleinfos_apply(scope int delegate(immutable(object.ModuleInfo*))) [0x7efd3b4314cb]
??:? int object.ModuleInfo.opApply(scope int delegate(object.ModuleInfo*)) [0x7efd3b41f17e]
??:? runModuleUnitTests [0x7efd3b4132f4]
??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int function(char[][])*).runAll() [0x7efd3b427b4a]
??:? _d_run_main2 [0x7efd3b427995]
??:? _d_run_main [0x7efd3b4277ed]
/usr/lib/ldc/x86_64-linux-gnu/include/d/core/internal/entrypoint.d:42 [0x556289fe2451]
??:? [0x7efd3ab67249]
??:? __libc_start_main [0x7efd3ab67304]
??:? [0x556289fb7420]
1/1 modules FAILED unittests
Error Program exited with code 1

CPU information:

alex@compy  xxhash-d/trunk lscpu                                                                                      22:21:08 24-08-12
Architecture:             x86_64
  CPU op-mode(s):         32-bit, 64-bit
  Address sizes:          48 bits physical, 48 bits virtual
  Byte Order:             Little Endian
CPU(s):                   24
  On-line CPU(s) list:    0-23
Vendor ID:                AuthenticAMD
  Model name:             AMD Ryzen 9 7900X 12-Core Processor
    CPU family:           25
    Model:                97
    Thread(s) per core:   2
    Core(s) per socket:   12
    Socket(s):            1
    Stepping:             2
    Frequency boost:      enabled
    CPU(s) scaling MHz:   52%
    CPU max MHz:          5732.7139
    CPU min MHz:          3000.0000
    BogoMIPS:             9382.49
    Flags:                fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall n
                          x mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfm
                          perf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lah
                          f_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext per
                          fctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp 
                          ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx
                          512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc
                           cqm_mbm_total cqm_mbm_local avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock n
                          rip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2av
                          ic v_spec_ctrl avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vp
                          opcntdq rdpid overflow_recov succor smca fsrm flush_l1d amd_lbr_pmc_freeze
Virtualization features:  
  Virtualization:         AMD-V
Caches (sum of all):      
  L1d:                    384 KiB (12 instances)
  L1i:                    384 KiB (12 instances)
  L2:                     12 MiB (12 instances)
  L3:                     64 MiB (2 instances)
NUMA:                     
  NUMA node(s):           1
  NUMA node0 CPU(s):      0-23
Vulnerabilities:          
  Gather data sampling:   Not affected
  Itlb multihit:          Not affected
  L1tf:                   Not affected
  Mds:                    Not affected
  Meltdown:               Not affected
  Mmio stale data:        Not affected
  Reg file data sampling: Not affected
  Retbleed:               Not affected
  Spec rstack overflow:   Mitigation; safe RET, no microcode
  Spec store bypass:      Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:             Mitigation; usercopy/swapgs barriers and __user pointer sanitization
  Spectre v2:             Mitigation; Enhanced / Automatic IBRS; IBPB conditional; STIBP always-on; RSB filling; PBRSB-eIBRS Not affecte
                          d; BHI Not affected
  Srbds:                  Not affected
  Tsx async abort:        Not affected

If _mm256_srli_epi64() was implemented I would just use that instead :)

p0nce commented 1 month ago

Hello, your unittest seems to pass here, what's your LDC version? (EDIT: and OS?)

p0nce commented 1 month ago

1.11.20 now implements _mm256_srli_epi64, please dub upgrade

I think you got trapped by an old LDC promoting your int 32 into a int4 equal to [32, 32, 32, 32], that instruction is a trap because of this, it would then asks a shift of (32 << 32) + 32 bits. That's why we advise to use _mm256_srli_epi64 instead of _mm256_srl_epi64

THAT SAID, it seems newer LDC prevent such implicit conversions. As said, I don't repro your unittest, which is odd.

apbryan commented 1 month ago

Thanks for responding and implementing _mm256_srli_epi64()!

Looking at the output more, I realized while my application was being compiled with -mattr=+avx2, intel-intrinsics was not. After changing:

dependency "intel-intrinsics" version="~>1.0"

to

dependency "intel-intrinsics" version="~>1.0" {                                                                             
    dflags "-mattr=+avx2" "-O3"                                                                                             
}

and also replacing _mm256_srl_epi64() with _mm256_srli_epi64(), my unittest now passes; though it does not pass when intel-intrinsics is not built with -mattr=+avx2

This is reproducible by me on debian 12 bookworm with both the repo version of LDC v1.30.0 and a freshly compiled v1.39.0

p0nce commented 4 weeks ago

I still can't repro on Windows or godbolt, I'm going to left it here. Probably you should be able to comment __builtin_ia32_psrlq128 in _mm_srl_epi64 to get it to work, let me know.

Probably need your LLVM version with ldc2 --version too.