]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/59539
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Dec 2013 16:50:06 +0000 (16:50 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Dec 2013 16:50:06 +0000 (16:50 +0000)
* config/i386/sse.md
(<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>,
<sse2_avx_avx512f>_loaddqu<mode><mask_name>): New expanders,
prefix existing define_insn names with *.

* gcc.target/i386/pr59539-1.c: New test.
* gcc.target/i386/pr59539-2.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206090 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/sse.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr59539-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59539-2.c [new file with mode: 0644]

index 46f1e9b64fce61a5cc3100cb45b68b4d1adf6424..83e8321f9c257afff0fdaa48da897189a56d5f98 100644 (file)
@@ -1,3 +1,11 @@
+2013-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/59539
+       * config/i386/sse.md
+       (<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>,
+       <sse2_avx_avx512f>_loaddqu<mode><mask_name>): New expanders,
+       prefix existing define_insn names with *.
+
 2013-12-18  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/arm/arm.c (arm_expand_epilogue_apcs_frame): Fix thinko.
index adedf44fc3146390408eb53466f41a3d8f7b5805..2cbbb14ccea45cd7bbaad0278a0a3917a5367070 100644 (file)
   DONE;
 })
 
-(define_insn "<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>"
+(define_expand "<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>"
+  [(set (match_operand:VF 0 "register_operand")
+       (unspec:VF [(match_operand:VF 1 "nonimmediate_operand")]
+         UNSPEC_LOADU))]
+  "TARGET_SSE && <mask_mode512bit_condition>"
+{
+  /* For AVX, normal *mov<mode>_internal pattern will handle unaligned loads
+     just fine if misaligned_operand is true, and without the UNSPEC it can
+     be combined with arithmetic instructions.  If misaligned_operand is
+     false, still emit UNSPEC_LOADU insn to honor user's request for
+     misaligned load.  */
+  if (TARGET_AVX
+      && misaligned_operand (operands[1], <MODE>mode)
+      /* FIXME: Revisit after AVX512F merge is completed.  */
+      && !<mask_applied>)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+      DONE;
+    }
+})
+
+(define_insn "*<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>"
   [(set (match_operand:VF 0 "register_operand" "=v")
        (unspec:VF
          [(match_operand:VF 1 "nonimmediate_operand" "vm")]
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
 
-(define_insn "<sse2_avx_avx512f>_loaddqu<mode><mask_name>"
+(define_expand "<sse2_avx_avx512f>_loaddqu<mode><mask_name>"
+  [(set (match_operand:VI_UNALIGNED_LOADSTORE 0 "register_operand")
+       (unspec:VI_UNALIGNED_LOADSTORE
+         [(match_operand:VI_UNALIGNED_LOADSTORE 1 "nonimmediate_operand")]
+         UNSPEC_LOADU))]
+  "TARGET_SSE2 && <mask_mode512bit_condition>"
+{
+  /* For AVX, normal *mov<mode>_internal pattern will handle unaligned loads
+     just fine if misaligned_operand is true, and without the UNSPEC it can
+     be combined with arithmetic instructions.  If misaligned_operand is
+     false, still emit UNSPEC_LOADU insn to honor user's request for
+     misaligned load.  */
+  if (TARGET_AVX
+      && misaligned_operand (operands[1], <MODE>mode)
+      /* FIXME: Revisit after AVX512F merge is completed.  */
+      && !<mask_applied>)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+      DONE;
+    }
+})
+
+(define_insn "*<sse2_avx_avx512f>_loaddqu<mode><mask_name>"
   [(set (match_operand:VI_UNALIGNED_LOADSTORE 0 "register_operand" "=v")
        (unspec:VI_UNALIGNED_LOADSTORE
          [(match_operand:VI_UNALIGNED_LOADSTORE 1 "nonimmediate_operand" "vm")]
index 730ce06a24b388cc4559a2eb2056eecc98155784..20a1bc59c4ff81898d4ad75a86cffdef580e1c04 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/59539
+       * gcc.target/i386/pr59539-1.c: New test.
+       * gcc.target/i386/pr59539-2.c: New test.
+
 2013-12-18  Nick Clifton  <nickc@redhat.com>
 
        * gcc.dg/pr32912-2.c: Fix for 16-bit targets.
diff --git a/gcc/testsuite/gcc.target/i386/pr59539-1.c b/gcc/testsuite/gcc.target/i386/pr59539-1.c
new file mode 100644 (file)
index 0000000..9b34053
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/59539 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+int
+foo (void *p1, void *p2)
+{
+  __m128i d1 = _mm_loadu_si128 ((__m128i *) p1);
+  __m128i d2 = _mm_loadu_si128 ((__m128i *) p2);
+  __m128i result = _mm_cmpeq_epi16 (d1, d2);
+  return _mm_movemask_epi8 (result);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59539-2.c b/gcc/testsuite/gcc.target/i386/pr59539-2.c
new file mode 100644 (file)
index 0000000..b53b8c4
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/59539 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx2" } */
+
+#include <immintrin.h>
+
+int
+foo (void *p1, void *p2)
+{
+  __m256i d1 = _mm256_loadu_si256 ((__m256i *) p1);
+  __m256i d2 = _mm256_loadu_si256 ((__m256i *) p2);
+  __m256i result = _mm256_cmpeq_epi16 (d1, d2);
+  return _mm256_movemask_epi8 (result);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu" 1 } } */