aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2023-11-23 16:17:57 +0100
committerUros Bizjak <ubizjak@gmail.com>2023-11-23 16:17:57 +0100
commitb2d17bdd45b582b93e89c00b04763a45f97d7a34 (patch)
tree5f16b583527b8ce62144e2e10c90a075dee60559
parent2f3f8952ff1736dd6a087ddb4106077db3502bb9 (diff)
downloadgcc-b2d17bdd45b582b93e89c00b04763a45f97d7a34.zip
gcc-b2d17bdd45b582b93e89c00b04763a45f97d7a34.tar.gz
gcc-b2d17bdd45b582b93e89c00b04763a45f97d7a34.tar.bz2
i386: Wrong code with __builtin_parityl [PR112672]
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.
-rw-r--r--gcc/config/i386/i386.md4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112672.c23
2 files changed, 26 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 99bb909..41de953 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20031,8 +20031,10 @@
"! 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
index 0000000..583e9fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr112672.c
@@ -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;
+}