]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Wrong code with __builtin_parityl [PR112672]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 23 Nov 2023 15:17:57 +0000 (16:17 +0100)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 23 Nov 2023 15:17:57 +0000 (16:17 +0100)
gen_parityhi2_cmp instruction clobbers its input operand, so use
a temporary register in the call to gen_parityhi2_cmp.

PR target/112672

gcc/ChangeLog:

* config/i386/i386.md (parityhi2):
Use temporary register in the call to gen_parityhi2_cmp.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr112672.c: New test.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr112672.c [new file with mode: 0644]

index 99bb909b244d525a10bff42d7f740b27a69da24a..41de9537a40539b4af9502bf1c85ad27f6213bcc 100644 (file)
   "! TARGET_POPCNT"
 {
   rtx scratch = gen_reg_rtx (QImode);
+  rtx tmp = gen_reg_rtx (HImode);
 
-  emit_insn (gen_parityhi2_cmp (operands[1]));
+  emit_move_insn (tmp, operands[1]);
+  emit_insn (gen_parityhi2_cmp (tmp));
 
   ix86_expand_setcc (scratch, ORDERED,
                     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
diff --git a/gcc/testsuite/gcc.target/i386/pr112672.c b/gcc/testsuite/gcc.target/i386/pr112672.c
new file mode 100644 (file)
index 0000000..583e9fd
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/112672 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef unsigned short u16;
+
+u16 g = 254;
+
+static inline u16
+foo (u16 u)
+{
+  u *= g;
+  return u + __builtin_parityl (u);
+}
+
+int
+main (void)
+{
+  u16 x = foo (4);
+  if (x != 4 * 254 + 1)
+    __builtin_abort ();
+  return 0;
+}