aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-02-20 13:03:51 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2025-02-25 13:47:52 -0800
commit892ee5ffba0760794a932e36771863a86ef2b271 (patch)
tree90ec6e0f0c32e2d2164a04df414765b84a711d52 /gcc
parentdf4565eaa9b02906a8fa6bb37845c0b4fdedaa20 (diff)
downloadgcc-892ee5ffba0760794a932e36771863a86ef2b271.zip
gcc-892ee5ffba0760794a932e36771863a86ef2b271.tar.gz
gcc-892ee5ffba0760794a932e36771863a86ef2b271.tar.bz2
i386: Fix pr101950-2.c [PR115028]
So what is happening here is that after r15-268-g9dbff9c05520a7, a move instruction still exists after combine and the register allocator choses different register allocation order for the xor and because the input operand of lzcntq is not the same as output operand, there is an extra xor that happens (due to an errata). This fixes the testcase by using loading from a pointer instead of a function argument directly. The register allocator has more freedom since the load has no hard register associated with it (rdi) so it can be in eax register right away. Tested for both -m32 and -m64 on x86_64-linux-gnu. gcc/testsuite/ChangeLog: PR testsuite/115028 * gcc.target/i386/pr101950-2.c: Use a pointer argument instead of the argument directly. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101950-2.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.target/i386/pr101950-2.c b/gcc/testsuite/gcc.target/i386/pr101950-2.c
index 896f1b4..ccc361e3 100644
--- a/gcc/testsuite/gcc.target/i386/pr101950-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr101950-2.c
@@ -6,14 +6,19 @@
/* { dg-final { scan-assembler-times "\txor\[ql]\t" 2 } } */
/* { dg-final { scan-assembler-times "\tsar\[ql]\t|\tcltd" 2 } } */
+/* Use pointers to avoid register allocation difference due to argument
+ and return register being different and the difference in selecting eax
+ for one the result of the xor vs selecting rdi due to the order of the
+ shift vs the not shift. */
+
int
-foo (long x)
+foo (long *x)
{
- return __builtin_clrsbl (x);
+ return __builtin_clrsbl (*x);
}
int
-bar (int x)
+bar (int *x)
{
- return __builtin_clrsb (x);
+ return __builtin_clrsb (*x);
}