Skip to content

Commit

Permalink
[X86] Ensure the _mm_test_all_ones macro does not reuse argument (PR6…
Browse files Browse the repository at this point in the history
…0006)

The macro _mm_test_all_ones(V) was defined as _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V))) - which could cause side effects depending on the source of the V value.

The _mm_cmpeq_epi32((V), (V)) trick was just to materialize an all-ones value, which can be more safely generated with _mm_set1_epi32(-1) .

Fixes #60006

Differential Revision: https://reviews.llvm.org/D142477

(cherry picked from commit c9b2823)
  • Loading branch information
RKSimon authored and tru committed Jan 27, 2023
1 parent 59325c9 commit 99777ef
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
2 changes: 1 addition & 1 deletion clang/lib/Headers/smmintrin.h
Expand Up @@ -1145,7 +1145,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testnzc_si128(__m128i __M,
/// A 128-bit integer vector containing the bits to be tested.
/// \returns TRUE if the bits specified in the operand are all set to 1; FALSE
/// otherwise.
#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V)))
#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_set1_epi32(-1))

/// Tests whether the specified bits in a 128-bit integer vector are
/// neither all zeros nor all ones.
Expand Down
10 changes: 10 additions & 0 deletions clang/test/CodeGen/X86/sse41-builtins.c
Expand Up @@ -401,3 +401,13 @@ float pr51324(__m128 a) {
// CHECK: extractelement <4 x float> %{{.*}}, i32 0
return _mm_round_ps(a, 0)[0];
}

// Ensure _mm_test_all_ones macro doesn't reuse argument
__m128i expensive_call();
int pr60006() {
// CHECK-LABEL: pr60006
// CHECK: call {{.*}} @expensive_call
// CHECK-NOT: call {{.*}} @expensive_call
// CHECK: call i32 @llvm.x86.sse41.ptestc(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
return _mm_test_all_ones(expensive_call());
}

0 comments on commit 99777ef

Please sign in to comment.