re PR rtl-optimization/51040 (ICE: RTL check: access of elt 1 of 'not' with last elt 0 in gen_rtx_fmt_ee_stat, at ./genrtl.h:33 with __atomic_nand_fetch())
PR rtl-optimization/51040 * optabs.c (expand_atomic_fetch_op): Patchup code for NAND should be AND followed by NOT. * builtins.c (expand_builtin_atomic_fetch_op): Patchup code for NAND should be AND followed by NOT. * testsuite/gcc.dg/atomic-noinline[-aux].c: Test no-inline NAND and patchup code. From-SVN: r181259
This commit is contained in:
parent
c8bf99b4e8
commit
154b68db9b
5 changed files with 51 additions and 5 deletions
|
@ -1,3 +1,13 @@
|
|||
2011-11-10 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR rtl-optimization/51040
|
||||
* optabs.c (expand_atomic_fetch_op): Patchup code for NAND should be AND
|
||||
followed by NOT.
|
||||
* builtins.c (expand_builtin_atomic_fetch_op): Patchup code for NAND
|
||||
should be AND followed by NOT.
|
||||
* testsuite/gcc.dg/atomic-noinline[-aux].c: Test no-inline NAND and
|
||||
patchup code.
|
||||
|
||||
2011-11-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* vec.h (VEC_BASE): If base is at offset 0 in the structure,
|
||||
|
|
|
@ -5460,8 +5460,17 @@ expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
|
|||
|
||||
/* Then issue the arithmetic correction to return the right result. */
|
||||
if (!ignore)
|
||||
ret = expand_simple_binop (mode, code, ret, val, NULL_RTX, true,
|
||||
OPTAB_LIB_WIDEN);
|
||||
{
|
||||
if (code == NOT)
|
||||
{
|
||||
ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
|
||||
OPTAB_LIB_WIDEN);
|
||||
ret = expand_simple_unop (mode, NOT, ret, target, true);
|
||||
}
|
||||
else
|
||||
ret = expand_simple_binop (mode, code, ret, val, target, true,
|
||||
OPTAB_LIB_WIDEN);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
11
gcc/optabs.c
11
gcc/optabs.c
|
@ -7875,8 +7875,15 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
|
|||
Fetch_before == after REVERSE_OP val. */
|
||||
if (!after)
|
||||
code = optab.reverse_code;
|
||||
result = expand_simple_binop (mode, code, result, val, target, true,
|
||||
OPTAB_LIB_WIDEN);
|
||||
if (code == NOT)
|
||||
{
|
||||
result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
|
||||
true, OPTAB_LIB_WIDEN);
|
||||
result = expand_simple_unop (mode, NOT, result, target, true);
|
||||
}
|
||||
else
|
||||
result = expand_simple_binop (mode, code, result, val, target,
|
||||
true, OPTAB_LIB_WIDEN);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,11 +40,24 @@ char __atomic_fetch_add_1 (char *p, char v, int i)
|
|||
*p = 1;
|
||||
}
|
||||
|
||||
short __atomic_fetch_add_2 (short *p, short v, short i)
|
||||
short __atomic_fetch_add_2 (short *p, short v, int i)
|
||||
{
|
||||
*p = 1;
|
||||
}
|
||||
|
||||
/* Really perform a NAND. PR51040 showed incorrect calculation of a
|
||||
non-inlined fetch_nand. */
|
||||
unsigned char
|
||||
__atomic_fetch_nand_1 (unsigned char *p, unsigned char v, int i)
|
||||
{
|
||||
unsigned char ret;
|
||||
|
||||
ret = *p;
|
||||
*p = ~(*p & v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __atomic_is_lock_free (int i, void *p)
|
||||
{
|
||||
return 10;
|
||||
|
|
|
@ -49,6 +49,13 @@ main ()
|
|||
if (__atomic_is_lock_free (4, 0) != 10)
|
||||
abort ();
|
||||
|
||||
/* PR 51040 was caused by arithmetic code not patching up nand_fetch properly
|
||||
when used an an external function. Look for proper return value here. */
|
||||
ac = 0x3C;
|
||||
bc = __atomic_nand_fetch (&ac, 0x0f, __ATOMIC_RELAXED);
|
||||
if (bc != ac)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue