This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C11-atomic] test invalid hoist across and acquire load


In the test below, we cannot cache either [x] or [y] neither before the load of flag1 nor the load of flag2. This is because the corresponding store/release can flush a different value of x or y:

+  if (__atomic_load_n (&flag1, __ATOMIC_ACQUIRE))
+    i = x + y;
+
+  if (__atomic_load_n (&flag2, __ATOMIC_ACQUIRE))
+    a = 10;
+  j = x + y;

For example, on x86-64, we are hoisting "x" and "y" before the load of flag2:

        movl    flag1(%rip), %eax
        movl    x(%rip), %edx		<-- hoist of X
        testl   %eax, %eax
        movl    y(%rip), %eax		<-- hoist of Y
        je      .L2
        leal    (%edx,%eax), %ecx
        movl    %ecx, i(%rip)
.L2:
        movl    flag2(%rip), %ecx
        testl   %ecx, %ecx
        je      .L3
        movl    $10, a(%rip)
.L3:
        addl    %edx, %eax		<-- x/y may have changed by the
					    acquire of flag2.
        movl    %eax, j(%rip)
        ret

(For that matter, we are also hoisting "x" before the actual test of flag1 as well, but I believe this is allowed since flag1 has already been loaded.)

The pass at fault here is the combine stack adjustment RTL pass. I have not looked into why this is happening, but I wanted to get this test into the branch lest we forget about it.

Is this OK for the branch? Is my understanding correct?

Aldy

Attachment: curr
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]