On Fri, Oct 28, 2011 at 4:52 PM, Richard Guenther <rguent...@suse.de> wrote:
> On Fri, 28 Oct 2011, Sergey Ostanevich wrote:
>
>> On Fri, Oct 28, 2011 at 12:16 PM, Richard Guenther <rguent...@suse.de> wrote:
>> > On Thu, 27 Oct 2011, Uros Bizjak wrote:
>> >
>> >> Hello!
>> >>
>> >> > Here's a patch for PR47698, which is about CMOV should not be
>> >> > generated for memory address marked as volatile.
>> >> > Successfully bootstrapped and passed make check on 
>> >> > x86_64-unknown-linux-gnu.
>> >>
>> >>
>> >>       PR rtl-optimization/47698
>> >>       * config/i386/i386.c (ix86_expand_int_movcc) prevent CMOV generation
>> >>       for volatile mem
>> >>
>> >>       PR rtl-optimization/47698
>> >>       * gcc.target/i386/47698.c: New test
>> >>
>> >> Please use punctuation marks and correct capitalization in ChangeLog 
>> >> entries.
>> >>
>> >> OTOH, do we want to fix this per-target, or in the middle-end?
>> >
>> > The middle-end pattern documentation does not say operands 2 and 3
>> > are not evaluated if they do not end up being stored, so a middle-end
>> > fix is more appropriate.
>> >
>> > Richard.
>> >
>>
>> I have two observations:
>>
>> - the code for CMOV is under #ifdef in the mddle-end, which is
>> explicitly marked as "have to be removed" (ifcvt.c:1446)
>> - I have no clear evidence all platforms that support conditional move
>> have the same semantics that lead to the PR
>>
>> I think the best way to address both concerns is to implement code
>> that relies on а new hookup "volatile-safe CMOV" that is false by
>> default.
>
> I suppose it's never safe for all architectures that support
> memory operands in the source operand.
>
> Richard.

ok, at least there should be no big problem of missing optimization
around volatile memory.

apparently the problem is here:

ifcvt.c:2539 there is a test for side effects of source (which is 'a'
in this case)

2539      if (! noce_operand_ok (a) || ! noce_operand_ok (b))
(gdb) p debug_rtx(a)
(mem/v/c/i:DI (symbol_ref:DI ("mmio") [flags 0x40] <var_decl
0x7ffff1339140 mmio>) [2 mmio+0 S8 A64])

but inside noce_operand_ok() there is a wrong order of tests:

2332      if (MEM_P (op))
2333        return ! side_effects_p (XEXP (op, 0));
2334
2335      if (side_effects_p (op))
2336        return FALSE;
2337

where XEXP removes the memory reference leaving just symbol reference,
that has no volatile attribute
#0  side_effects_p (x=0x7ffff149c660) at ../../gcc/rtlanal.c:2152
(gdb) p debug_rtx(x)
(symbol_ref:DI ("mmio") [flags 0x40] <var_decl 0x7ffff1339140 mmio>)

Is the following fix is Ok?
I'm testing it so far.

Sergos

diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 784e2e8..3b05c2a 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2329,12 +2329,12 @@ noce_operand_ok (const_rtx op)
 {
   /* We special-case memories, so handle any of them with
      no address side effects.  */
-  if (MEM_P (op))
-    return ! side_effects_p (XEXP (op, 0));
-
   if (side_effects_p (op))
     return FALSE;

+  if (MEM_P (op))
+    return ! side_effects_p (XEXP (op, 0));
+
   return ! may_trap_p (op);
 }

diff --git a/gcc/testsuite/gcc.target/i386/47698.c
b/gcc/testsuite/gcc.target/i386/47698.c
new file mode 100644
index 0000000..2c75109
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/47698.c
@@ -0,0 +1,10 @@
+/* { dg-options "-Os" } */
+/* { dg-final { scan-assembler-not "cmov" } } */
+
+extern volatile unsigned long mmio;
+unsigned long foo(int cond)
+{
+      if (cond)
+              return mmio;
+        return 0;
+}

Attachment: 47698.patch
Description: Binary data

Reply via email to