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 <[email protected]>
PR target/81015
Revert:
2016-12-14 Uros Bizjak <[email protected]>
PR target/59874
* config/i386/i386.md (*ctzhi2): New insn_and_split pattern.
(*clzhi2): Ditto.
testsuite/ChangeLog:
2017-06-08 Uros Bizjak <[email protected]>
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.
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 ();
+}