Skip to content

Commit eaa3858

Browse files
committed
x86: fix the NLT, NLE and GE predicates in simde_mm_cmp_sd and simde_mm_cmp_ss
Both LSX branches complemented the wrong comparison, the same way simde_mm256_cmp_pd did: NLT used cult and NLE used cule, which are false for unordered operands where the negated predicates have to be true, and GE used clt, which is true for them where GE has to be false. Use clt and cle for the negated predicates and cult for GE. simde_mm_cmp_ss also selected its "always false" and "always true" cases with SIMDE_LOONGARCH_LASX_NATIVE and wrote a_.i32[0] there, so those two cases went through a different union member than every other case. When the function is not inlined (SIMDE_CONSTRAINED_COMPILATION at -O1 and above) GCC then dropped the upper lanes, leaving _mm_cmp_ss with imm8 11, 15, 27 or 31 with garbage above the low element. Route them through a_.lsx_i64 like the rest. Extend test_simde_mm_cmp_sd and test_simde_mm_cmp_ss with NaN inputs, which are the only ones that tell the ordered and unordered predicates apart.
1 parent e489066 commit eaa3858

2 files changed

Lines changed: 60 additions & 10 deletions

File tree

‎simde/x86/avx.h‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,7 +2726,7 @@ simde_mm_cmp_sd (simde__m128d a, simde__m128d b, const int imm8)
27262726
case SIMDE_CMP_NLT_UQ:
27272727
case SIMDE_CMP_NLT_US:
27282728
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2729-
t_ = __lsx_vfcmp_cult_d(a_.lsx_f64, b_.lsx_f64);
2729+
t_ = __lsx_vfcmp_clt_d(a_.lsx_f64, b_.lsx_f64);
27302730
a_.lsx_i64 = __lsx_vextrins_d(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
27312731
#else
27322732
a_.i64[0] = !(a_.f64[0] < b_.f64[0]) ? ~INT64_C(0) : INT64_C(0);
@@ -2736,7 +2736,7 @@ simde_mm_cmp_sd (simde__m128d a, simde__m128d b, const int imm8)
27362736
case SIMDE_CMP_NLE_UQ:
27372737
case SIMDE_CMP_NLE_US:
27382738
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2739-
t_ = __lsx_vfcmp_cule_d(a_.lsx_f64, b_.lsx_f64);
2739+
t_ = __lsx_vfcmp_cle_d(a_.lsx_f64, b_.lsx_f64);
27402740
a_.lsx_i64 = __lsx_vextrins_d(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
27412741
#else
27422742
a_.i64[0] = !(a_.f64[0] <= b_.f64[0]) ? ~INT64_C(0) : INT64_C(0);
@@ -2787,7 +2787,7 @@ simde_mm_cmp_sd (simde__m128d a, simde__m128d b, const int imm8)
27872787
case SIMDE_CMP_GE_OQ:
27882788
case SIMDE_CMP_GE_OS:
27892789
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2790-
t_ = __lsx_vfcmp_clt_d(a_.lsx_f64, b_.lsx_f64);
2790+
t_ = __lsx_vfcmp_cult_d(a_.lsx_f64, b_.lsx_f64);
27912791
a_.lsx_i64 = __lsx_vextrins_d(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
27922792
#else
27932793
a_.i64[0] = (a_.f64[0] >= b_.f64[0]) ? ~INT64_C(0) : INT64_C(0);
@@ -2891,7 +2891,7 @@ simde_mm_cmp_ss (simde__m128 a, simde__m128 b, const int imm8)
28912891
case SIMDE_CMP_NLT_UQ:
28922892
case SIMDE_CMP_NLT_US:
28932893
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2894-
t_ = __lsx_vfcmp_cult_s(a_.lsx_f32, b_.lsx_f32);
2894+
t_ = __lsx_vfcmp_clt_s(a_.lsx_f32, b_.lsx_f32);
28952895
a_.lsx_i64 = __lsx_vextrins_w(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
28962896
#else
28972897
a_.i32[0] = !(a_.f32[0] < b_.f32[0]) ? ~INT32_C(0) : INT32_C(0);
@@ -2901,7 +2901,7 @@ simde_mm_cmp_ss (simde__m128 a, simde__m128 b, const int imm8)
29012901
case SIMDE_CMP_NLE_UQ:
29022902
case SIMDE_CMP_NLE_US:
29032903
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2904-
t_ = __lsx_vfcmp_cule_s(a_.lsx_f32, b_.lsx_f32);
2904+
t_ = __lsx_vfcmp_cle_s(a_.lsx_f32, b_.lsx_f32);
29052905
a_.lsx_i64 = __lsx_vextrins_w(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
29062906
#else
29072907
a_.i32[0] = !(a_.f32[0] <= b_.f32[0]) ? ~INT32_C(0) : INT32_C(0);
@@ -2946,8 +2946,8 @@ simde_mm_cmp_ss (simde__m128 a, simde__m128 b, const int imm8)
29462946

29472947
case SIMDE_CMP_FALSE_OQ:
29482948
case SIMDE_CMP_FALSE_OS:
2949-
#if defined(SIMDE_LOONGARCH_LASX_NATIVE)
2950-
a_.lsx_i32[0] = INT32_C(0);
2949+
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2950+
a_.lsx_i64 = __lsx_vextrins_w(a_.lsx_i64, __lsx_vreplgr2vr_w(INT32_C(0)), 0x00);
29512951
#else
29522952
a_.i32[0] = INT32_C(0);
29532953
#endif
@@ -2956,7 +2956,7 @@ simde_mm_cmp_ss (simde__m128 a, simde__m128 b, const int imm8)
29562956
case SIMDE_CMP_GE_OQ:
29572957
case SIMDE_CMP_GE_OS:
29582958
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2959-
t_ = __lsx_vfcmp_clt_s(a_.lsx_f32, b_.lsx_f32);
2959+
t_ = __lsx_vfcmp_cult_s(a_.lsx_f32, b_.lsx_f32);
29602960
a_.lsx_i64 = __lsx_vextrins_w(a_.lsx_i64, __lsx_vnor_v(t_, t_), 0x00);
29612961
#else
29622962
a_.i32[0] = (a_.f32[0] >= b_.f32[0]) ? ~INT32_C(0) : INT32_C(0);
@@ -2974,8 +2974,8 @@ simde_mm_cmp_ss (simde__m128 a, simde__m128 b, const int imm8)
29742974

29752975
case SIMDE_CMP_TRUE_UQ:
29762976
case SIMDE_CMP_TRUE_US:
2977-
#if defined(SIMDE_LOONGARCH_LASX_NATIVE)
2978-
a_.lsx_i32[0] = ~INT32_C(0);
2977+
#if defined(SIMDE_LOONGARCH_LSX_NATIVE)
2978+
a_.lsx_i64 = __lsx_vextrins_w(a_.lsx_i64, __lsx_vreplgr2vr_w(~INT32_C(0)), 0x00);
29792979
#else
29802980
a_.i32[0] = ~INT32_C(0);
29812981
#endif

‎test/x86/avx.c‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5843,6 +5843,31 @@ test_simde_mm_cmp_sd(SIMDE_MUNIT_TEST_ARGS) {
58435843
r = simde_mm_cmp_sd(a, b, 31);
58445844
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
58455845

5846+
/* The negated predicates have to be true for unordered operands, and their
5847+
* non-negated counterparts false; only NaN inputs tell the two apart. */
5848+
a = simde_mm_setr_pd(SIMDE_MATH_NAN, SIMDE_FLOAT64_C( 987.65));
5849+
b = simde_mm_setr_pd(SIMDE_FLOAT64_C( 0.00), SIMDE_FLOAT64_C( 123.45));
5850+
5851+
e = simde_mm_move_sd(a, simde_x_mm_setone_pd());
5852+
r = simde_mm_cmp_sd(a, b, 5);
5853+
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
5854+
5855+
r = simde_mm_cmp_sd(a, b, 6);
5856+
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
5857+
5858+
e = simde_mm_move_sd(a, simde_mm_setzero_pd());
5859+
r = simde_mm_cmp_sd(a, b, 13);
5860+
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
5861+
5862+
/* The always-false and always-true predicates still have to pass the upper
5863+
* element through. */
5864+
r = simde_mm_cmp_sd(a, b, 11);
5865+
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
5866+
5867+
e = simde_mm_move_sd(a, simde_x_mm_setone_pd());
5868+
r = simde_mm_cmp_sd(a, b, 31);
5869+
simde_assert_m128i_u64(simde_mm_castpd_si128(r), ==, simde_mm_castpd_si128(e));
5870+
58465871
return 0;
58475872
}
58485873

@@ -6042,6 +6067,31 @@ test_simde_mm_cmp_ss(SIMDE_MUNIT_TEST_ARGS) {
60426067
r = simde_mm_cmp_ss(a, b, 31);
60436068
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
60446069

6070+
/* The negated predicates have to be true for unordered operands, and their
6071+
* non-negated counterparts false; only NaN inputs tell the two apart. */
6072+
a = simde_mm_setr_ps(SIMDE_MATH_NAN, SIMDE_FLOAT32_C( 1.00), SIMDE_FLOAT32_C( 2.00), SIMDE_FLOAT32_C( 3.00));
6073+
b = simde_mm_setr_ps(SIMDE_FLOAT32_C( 0.00), SIMDE_FLOAT32_C( 1.00), SIMDE_FLOAT32_C( 5.00), SIMDE_FLOAT32_C( 3.00));
6074+
6075+
e = simde_mm_move_ss(a, simde_x_mm_setone_ps());
6076+
r = simde_mm_cmp_ss(a, b, 5);
6077+
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
6078+
6079+
r = simde_mm_cmp_ss(a, b, 6);
6080+
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
6081+
6082+
e = simde_mm_move_ss(a, simde_mm_setzero_ps());
6083+
r = simde_mm_cmp_ss(a, b, 13);
6084+
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
6085+
6086+
/* The always-false and always-true predicates still have to pass the upper
6087+
* elements through. */
6088+
r = simde_mm_cmp_ss(a, b, 11);
6089+
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
6090+
6091+
e = simde_mm_move_ss(a, simde_x_mm_setone_ps());
6092+
r = simde_mm_cmp_ss(a, b, 31);
6093+
simde_assert_m128i_u32(simde_mm_castps_si128(r), ==, simde_mm_castps_si128(e));
6094+
60456095
return 0;
60466096
}
60476097

0 commit comments

Comments
 (0)