[PR tree-optimization/52558]: RFC: questions on store data race
Aldy Hernandez
aldyh@redhat.com
Tue Apr 17 15:04:00 GMT 2012
On 04/13/12 18:22, Boehm, Hans wrote:
>
>
>> -----Original Message-----
>> From: Aldy Hernandez [mailto:aldyh@redhat.com]
>> Sent: Thursday, April 12, 2012 3:12 PM
>> To: Richard Guenther
>> Cc: Andrew MacLeod; Boehm, Hans; gcc-patches; Torvald Riegel
>> Subject: [PR tree-optimization/52558]: RFC: questions on store data
>> race
>>
>> Here we have a testcase that affects both the C++ memory model and
>> transactional memory.
>>
>> [Hans, this is caused by the same problem that is causing the
>> speculative register promotion issue you and Torvald pointed me at].
>>
>> In the following testcase (adapted from the PR), the loop invariant
>> motion pass caches a pre-existing value for g_2, and then performs a
>> store to g_2 on every path, causing a store data race:
>>
>> int g_1 = 1;
>> int g_2 = 0;
>>
>> int func_1(void)
>> {
>> int l;
>> for (l = 0; l< 1234; l++)
>> {
>> if (g_1)
>> return l;
>> else
>> g_2 = 0; <-- Store to g_2 should only happen if !g_1
>> }
>> return 999;
>> }
>>
>> This gets transformed into something like:
>>
>> g_2_lsm = g_2;
>> if (g_1) {
>> g_2 = g_2_lsm; // boo! hiss!
>> return 0;
>> } else {
>> g_2_lsm = 0;
>> g_2 = g_2_lsm;
>> }
>>
>> The spurious write to g_2 could cause a data race.
> Presumably the g_2_lsm = g_2 is actually outside the loop?
>
> Why does the second g_2 = g_2_lsm; get introduced? I would have expected it before the return. Was the example just over-abbreviated?
There is some abbreviation going on :). To be exact, this is what -O2
currently produces for the lim1 pass.
<bb 2>:
pretmp.4_1 = g_1;
g_2_lsm.6_12 = g_2;
<bb 3>:
# l_13 = PHI <l_6(5), 0(2)>
# g_2_lsm.6_10 = PHI <g_2_lsm.6_11(5), g_2_lsm.6_12(2)>
g_1.0_4 = pretmp.4_1;
if (g_1.0_4 != 0)
goto <bb 7>;
else
goto <bb 4>;
<bb 4>:
g_2_lsm.6_11 = 0;
l_6 = l_13 + 1;
if (l_6 != 1234)
goto <bb 5>;
else
goto <bb 8>;
<bb 8>:
# g_2_lsm.6_18 = PHI <g_2_lsm.6_11(4)>
g_2 = g_2_lsm.6_18;
goto <bb 6>;
<bb 5>:
goto <bb 3>;
<bb 7>:
# g_2_lsm.6_17 = PHI <g_2_lsm.6_10(3)>
# l_19 = PHI <l_13(3)>
g_2 = g_2_lsm.6_17;
<bb 6>:
# l_2 = PHI <l_19(7), 999(8)>
return l_2;
So yes, there seems to be another write to g_2 inside the else, but
probably because we have merged some basic blocks along the way.
>
> Other than that, this sounds right to me. So does Richard's flag-based version, which is the approach I would have originally expected. But that clearly costs you a register. It would be interesting to see how they compare.
I am working on the flag based approach.
Thanks to both of you.
More information about the Gcc-patches
mailing list