Hi all,

The pointer conversion to wider type under macro would not consider
whether the higher bit is cleaned or not. It will lead to unexpected
cmp result.

After this change, it will throw an incompatible pointer type error just
like -O2 does currently.

Bootstraped and tested on x86_64-pc-linux-gnu. Ok for trunk and
backport to GCC14/13?

Thx,
Haochen

gcc/ChangeLog:

        * config/i386/cmpccxaddintrin.h (_cmpccxadd_epi32): Do not do
        type conversion for pointer.
        (_cmpccxadd_epi64): Ditto.

gcc/testsuite/ChangeLog:

        * gcc.target/i386/cmpccxadd-1b.c: New test.
---
 gcc/config/i386/cmpccxaddintrin.h            |  6 +++---
 gcc/testsuite/gcc.target/i386/cmpccxadd-1b.c | 15 +++++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/cmpccxadd-1b.c

diff --git a/gcc/config/i386/cmpccxaddintrin.h 
b/gcc/config/i386/cmpccxaddintrin.h
index 39f368ffc08..9349fb00c1b 100644
--- a/gcc/config/i386/cmpccxaddintrin.h
+++ b/gcc/config/i386/cmpccxaddintrin.h
@@ -72,11 +72,11 @@ _cmpccxadd_epi64 (long long *__A, long long __B, long long 
__C,
 }
 #else
 #define _cmpccxadd_epi32(A,B,C,D) \
-  __builtin_ia32_cmpccxadd ((int *) (A), (int) (B), (int) (C), \
+  __builtin_ia32_cmpccxadd ((A), (int) (B), (int) (C), \
                            (_CMPCCX_ENUM) (D))
 #define _cmpccxadd_epi64(A,B,C,D) \
-  __builtin_ia32_cmpccxadd64 ((long long *) (A), (long long) (B), \
-                             (long long) (C), (_CMPCCX_ENUM) (D))
+  __builtin_ia32_cmpccxadd64 ((A), (long long) (B), (long long) (C), \
+                             (_CMPCCX_ENUM) (D))
 #endif
 
 #ifdef __DISABLE_CMPCCXADD__
diff --git a/gcc/testsuite/gcc.target/i386/cmpccxadd-1b.c 
b/gcc/testsuite/gcc.target/i386/cmpccxadd-1b.c
new file mode 100644
index 00000000000..7d20325da50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpccxadd-1b.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O0 -mcmpccxadd" } */
+#include <x86gprintrin.h>
+
+short *a;
+int b, c;
+int *d;
+long long e, f;
+
+void extern
+cmpccxadd_test(void)
+{
+  b = _cmpccxadd_epi32 (a, b, c, _CMPCCX_O); /* { dg-error "incompatible 
pointer type" } */
+  e = _cmpccxadd_epi64 (d, e, f, _CMPCCX_O); /* { dg-error "incompatible 
pointer type" } */
+}
-- 
2.31.1

Reply via email to