diff mbox

[i386] : Fix PR81015, Bad codegen for __builtin_clz(unsigned short)

Message ID CAFULd4bgC0HhbxsXB2Mucd6yVRpMr+C-Vq3hLUtfKhU2CZtQsw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak June 8, 2017, 5:32 p.m. UTC
Hello!

Attached patch removes invalid substitution of zero-extended HImode
operands with HImode operation. CLZ returns different value when
operating on SImode value vs. HImode value.

2017-06-08  Uros Bizjak  <ubizjak@gmail.com>

    PR target/81015
    Revert:
    2016-12-14  Uros Bizjak  <ubizjak@gmail.com>

    PR target/59874
    * config/i386/i386.md (*ctzhi2): New insn_and_split pattern.
    (*clzhi2): Ditto.

testsuite/ChangeLog:

2017-06-08  Uros Bizjak  <ubizjak@gmail.com>

    PR target/81015
    * gcc.target/i386/pr59874-1.c (foo): Call __builtin_ctzs.
    * gcc.target/i386/pr59874-2.c (foo): Call __builtin_clzs.
    * gcc.target/i386/pr81015.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN, will be committed to gcc-7 branch.

Uros.
diff mbox

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 249018)
+++ config/i386/i386.md	(working copy)
@@ -12762,24 +12762,6 @@ 
    (set_attr "znver1_decode" "vector")
    (set_attr "mode" "<MODE>")])
 
-(define_insn_and_split "*ctzhi2"
-  [(set (match_operand:SI 0 "register_operand")
-	(ctz:SI
-	  (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_BMI
-   && can_create_pseudo_p ()"
-  "#"
-  "&& 1"
-  [(const_int 0)]
-{
-  rtx tmp = gen_reg_rtx (HImode);
-
-  emit_insn (gen_tzcnt_hi (tmp, operands[1]));
-  emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
-  DONE;
-})
-
 (define_insn_and_split "ctz<mode>2"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
 	(ctz:SWI48
@@ -12899,24 +12881,6 @@ 
   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
 })
 
-(define_insn_and_split "*clzhi2"
-  [(set (match_operand:SI 0 "register_operand")
-	(clz:SI
-	  (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_LZCNT
-   && can_create_pseudo_p ()"
-  "#"
-  "&& 1"
-  [(const_int 0)]
-{
-  rtx tmp = gen_reg_rtx (HImode);
-
-  emit_insn (gen_lzcnt_hi (tmp, operands[1]));
-  emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
-  DONE;
-})
-
 (define_insn_and_split "clz<mode>2_lzcnt"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
 	(clz:SWI48
Index: testsuite/gcc.target/i386/pr59874-1.c
===================================================================
--- testsuite/gcc.target/i386/pr59874-1.c	(revision 249018)
+++ testsuite/gcc.target/i386/pr59874-1.c	(working copy)
@@ -6,5 +6,5 @@ 
 unsigned int
 foo (unsigned short x)
 {
-  return x ? __builtin_ctz (x) : 16U;
+  return x ? __builtin_ctzs (x) : 16U;
 }
Index: testsuite/gcc.target/i386/pr59874-2.c
===================================================================
--- testsuite/gcc.target/i386/pr59874-2.c	(revision 249018)
+++ testsuite/gcc.target/i386/pr59874-2.c	(working copy)
@@ -6,5 +6,5 @@ 
 unsigned int
 foo (unsigned short x)
 {
-  return x ? __builtin_clz (x) : 16U;
+  return x ? __builtin_clzs (x) : 16U;
 }
Index: testsuite/gcc.target/i386/pr81015.c
===================================================================
--- testsuite/gcc.target/i386/pr81015.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr81015.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -mlzcnt" } */
+/* { dg-require-effective-target lzcnt } */
+
+#include "lzcnt-check.h"
+
+int
+__attribute__ ((noinline, noclone))
+foo (unsigned short a)
+{
+  return __builtin_clz (a);
+}
+
+static void
+lzcnt_test ()
+{
+  int res = foo (1);
+
+  if (res != 31)
+    abort ();
+}