Bug 37640 - __sync_lock_test_and_set on PPC64 causes ICE
Summary: __sync_lock_test_and_set on PPC64 causes ICE
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.4.0
Assignee: Andrew Pinski
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: ice-on-valid-code, patch
Depends on:
Blocks:
 
Reported: 2008-09-24 16:30 UTC by Anton Blanchard
Modified: 2008-11-18 02:27 UTC (History)
3 users (show)

See Also:
Host:
Target: powerpc64-linux-gnu-gnu
Build:
Known to work:
Known to fail: 4.3.0 4.4.0
Last reconfirmed: 2008-09-28 21:17:12


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Anton Blanchard 2008-09-24 16:30:57 UTC
A gcc build from today (gcc version 4.4.0 20080924) gets an ICE on PowerPC when building this (admittedly broken) code:

# gcc -m64 -O2 -c test.c

struct foo {
        int a;
        char lock;
};
struct foo *foo;

void testcase()
{
        __sync_lock_test_and_set(&(foo->lock), 0);
}

It compiles if building 32bit. Even so, I wonder if gcc should warn when the variable is incompatible with __sync_* builtins.
Comment 1 Andrew Pinski 2008-09-24 19:55:00 UTC
How is this broken code?
Comment 2 Anton Blanchard 2008-09-24 20:07:21 UTC
After reading the gcc documentation I guess it is valid, and the 32bit lwarx/stwcx will overlap but not change surrounding memory.
Comment 3 Andrew Pinski 2008-09-24 20:16:23 UTC
Something like this fixes the issue:
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c      (revision 140638)
+++ config/rs6000/rs6000.c      (working copy)
@@ -14082,7 +14082,8 @@ rs6000_expand_compare_and_swapqhi (rtx d
   HOST_WIDE_INT imask = GET_MODE_MASK (mode);
 
   /* Shift amount for subword relative to aligned word.  */
-  addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
+  addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
+  addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
   shift = gen_reg_rtx (SImode);
   emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
                         GEN_INT (shift_mask)));

--- CUT ---
gen_lowpart_common does not work on non regs so force the addition to memory first and then get the lowerpart.
Comment 4 Andrew Pinski 2008-09-28 21:17:11 UTC
Mine, as far as I can tell this never worked.
Comment 5 Andrew Pinski 2008-09-28 23:07:19 UTC
Fixed on the trunk.
Comment 6 Andrew Pinski 2008-09-28 23:08:24 UTC
Subject: Bug 37640

Author: pinskia
Date: Sun Sep 28 23:07:01 2008
New Revision: 140740

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140740
Log:
2008-09-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        PR target/37640
        * config/rs6000/rs6000.c (rs6000_expand_compare_and_swapqhi): Force
        address to a register before taking the lower part.

2008-09-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        PR target/37640
        * gcc.c-torture/compile/sync-3.c: New testcase to check that
	addresses of non zero offset works.


Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/sync-3.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/rs6000.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Ben Elliston 2008-11-18 22:09:22 UTC
Subject: Bug 37640

Author: bje
Date: Tue Nov 18 22:07:58 2008
New Revision: 141980

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141980
Log:
	Backport from mainline:

	PR target/37640
	2008-09-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>

	* config/rs6000/rs6000.c (rs6000_expand_compare_and_swapqhi): Force
	address to a register before taking the lower part.

testsuite/
	* gcc.c-torture/compile/sync-3.c: New testcase to check that
	addresses of non zero offset works.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gcc.c-torture/compile/sync-3.c
Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/config/rs6000/rs6000.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog