[PATCH] Fix up bmi_bextr_<mode> (PR target/57623)

Jakub Jelinek jakub@redhat.com
Mon Jun 17 16:12:00 GMT 2013


Hi!

This instruction has the predicates/constraints wrong, the r/m argument is
the middle-one, the value from which it should be extracted, rather than
the packed start/length argument.  This got broken with PR50766, where the
patch hasn't touched just BMI2, but for unknown reasons also this BMI
instruction which was handled right in GCC 4.6.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8/4.7?

BTW, the AVX2 docs document _bextr_u{32,64} 3 argument intrinsics, rather
than the __bextr_u{32,64} 2 argument intrinsics we have in GCC right now.
Something to fix up (as the names are different, perhaps we can both the old
ones and the new ones implemented say as return __bextr_u32 (x, (y & 255) |
(z << 8)); or similar)?

2013-06-17  Jakub Jelinek  <jakub@redhat.com>

	PR target/57623
	* config/i386/i386.md (bmi_bextr_<mode>): Swap predicates and
	constraints of operand 1 and 2.

	* gcc.target/i386/bmi-bextr-3.c: New test.

--- gcc/config/i386/i386.md.jj	2013-06-09 20:29:02.000000000 +0200
+++ gcc/config/i386/i386.md	2013-06-15 18:24:48.942362202 +0200
@@ -11679,8 +11679,8 @@ (define_insn "*bmi_andn_<mode>"
 
 (define_insn "bmi_bextr_<mode>"
   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
-        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
-                       (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
+        (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
+                       (match_operand:SWI48 2 "register_operand" "r,r")]
                        UNSPEC_BEXTR))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_BMI"
--- gcc/testsuite/gcc.target/i386/bmi-bextr-3.c.jj	2013-06-17 09:48:47.789600664 +0200
+++ gcc/testsuite/gcc.target/i386/bmi-bextr-3.c	2013-06-17 09:48:37.000000000 +0200
@@ -0,0 +1,31 @@
+/* PR target/57623 */
+/* { dg-do assemble { target bmi } } */
+/* { dg-options "-O2 -mbmi" } */
+
+#include <x86intrin.h>
+
+unsigned int
+f1 (unsigned int x, unsigned int *y)
+{
+  return __bextr_u32 (x, *y);
+}
+
+unsigned int
+f2 (unsigned int *x, unsigned int y)
+{
+  return __bextr_u32 (*x, y);
+}
+
+#ifdef  __x86_64__
+unsigned long long
+f3 (unsigned long long x, unsigned long long *y)
+{
+  return __bextr_u64 (x, *y);
+}
+
+unsigned long long
+f4 (unsigned long long *x, unsigned long long y)
+{
+  return __bextr_u64 (*x, y);
+}
+#endif

	Jakub



More information about the Gcc-patches mailing list