Commit 154b68db by Andrew MacLeod Committed by Andrew Macleod

re PR rtl-optimization/51040 (ICE: RTL check: access of elt 1 of 'not' with last…

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
parent c8bf99b4
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;
}
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment