GCC Compiler Optimization ignores or mistreats MFENCE memory barrier related instruction

2018-04-13 Thread Vivek Kinhekar
Hi,


We are trying to create a memory barrier with following testcase.

=
#include 

void Test()
{
float fDivident = 0.1f;
float fResult = 0.0f;

fResult = ( fDivident / fResult );

__asm volatile ("mfence" ::: "memory");

printf("\nResult: %f\n", fResult);
}
==



'mfence' performs a serializing operation on all load-from-memory and 
store-to-memory instructions that were issued prior the MFENCE instruction. 
This serializing operation guarantees that every load and store instruction 
that precedes the MFENCE instruction in program order becomes globally visible 
before any load or store instruction that follows the MFENCE instruction.

The mfence instruction with memory clobber asm instruction should create a 
barrier between division and printf instructions.



When the testcase is compiled with optimization options O1 and above it can be 
observed that the mfence instruction is reordered and precedes division 
instruction.

We expected that the two sets of assembly instructions, one pertaining to 
division operation and another pertaining to the printf operation, would not 
get mixed up on reordering by the GCC compiler optimizer because of the 
presence of the __asm volatile ("mfence" ::: "memory"); line between them.



But, the generated assembly, which is inlined below for reference, isn't quite 
right as per our expectation.



pushl   %ebp# 23*pushsi2[length = 1]
movl%esp, %ebp  # 24*movsi_internal/1   [length = 2]
subl$24, %esp   # 25pro_epilogue_adjust_stack_si_add/1  
[length = 3]
mfence
fldz# 20*movxf_internal/3   [length = 2]
fdivrs  .LC0# 13*fop_xf_4_i387/1[length = 6]

You may note that the mfence instruction is generated before the fdivrs 
instruction.

Can you please let us know if the usage of the "asm (mfence)" instruction as 
given in the above testcase is the right way of creating the expected memory 
barrier between the two sets of instructions pertaining to the division and 
printf operations, respectively or not?

If yes, then we think, it's a bug in Compiler. Could you please confirm?

If no, then what is the correct usage of "asm (mfence)" so as to get/ achieve 
the memory barrier functionality as expected in the above testcase?

Thanks,
Vivek Kinhekar


RE: GCC Compiler Optimization ignores or mistreats MFENCE memory barrier related instruction

2018-04-13 Thread Vivek Kinhekar
Thanks for the quick response, Alexander!

Regards,
Vivek Kinhekar
+91-7709046470

-Original Message-
From: Alexander Monakov  
Sent: Friday, April 13, 2018 5:58 PM
To: Vivek Kinhekar 
Cc: gcc@gcc.gnu.org
Subject: Re: GCC Compiler Optimization ignores or mistreats MFENCE memory 
barrier related instruction

On Fri, 13 Apr 2018, Vivek Kinhekar wrote:
> The mfence instruction with memory clobber asm instruction should 
> create a barrier between division and printf instructions.

No, floating-point division does not touch memory, so the asm does not (and 
need not) restrict its motion.

Alexander


RE: GCC Compiler Optimization ignores or mistreats MFENCE memory barrier related instruction

2018-04-13 Thread Vivek Kinhekar
Hello Alexander,

In the given testcase, the generated fdivrs instruction performs the division 
of a symbol ref (memory value) by FPU Stack Register and stores the value in 
FPU Stack Register. 

Please find the following RTL Dump of the fdivrs instruction generated. It 
clearly access the memory for read access!
===
#(insn:TI 13 20 16 2 (set (reg:XF 8 st)
#(div:XF (float_extend:XF (mem/u/c:SF (symbol_ref/u:SI ("*.LC0") [flags 
0x2]) [4 S4 A32]))
#(reg:XF 8 st)))  {*fop_xf_4_i387}
# (nil))
fdivrs  .LC0# 13*fop_xf_4_i387/1[length = 6]
===

Are we missing anything subtle here?

Regards,
Vivek Kinhekar

-Original Message-
From: Alexander Monakov  
Sent: Friday, April 13, 2018 5:58 PM
To: Vivek Kinhekar 
Cc: gcc@gcc.gnu.org
Subject: Re: GCC Compiler Optimization ignores or mistreats MFENCE memory 
barrier related instruction

On Fri, 13 Apr 2018, Vivek Kinhekar wrote:
> The mfence instruction with memory clobber asm instruction should 
> create a barrier between division and printf instructions.

No, floating-point division does not touch memory, so the asm does not (and 
need not) restrict its motion.

Alexander


RE: GCC Compiler Optimization ignores or mistreats MFENCE memory barrier related instruction

2018-04-13 Thread Vivek Kinhekar
Oh! Thanks for the quick response, Jakub.

Regards,
Vivek Kinhekar

-Original Message-
From: Jakub Jelinek  
Sent: Friday, April 13, 2018 7:08 PM
To: Vivek Kinhekar 
Cc: Alexander Monakov ; gcc@gcc.gnu.org
Subject: Re: GCC Compiler Optimization ignores or mistreats MFENCE memory 
barrier related instruction

On Fri, Apr 13, 2018 at 01:34:21PM +, Vivek Kinhekar wrote:
> Hello Alexander,
> 
> In the given testcase, the generated fdivrs instruction performs the 
> division of a symbol ref (memory value) by FPU Stack Register and 
> stores the value in FPU Stack Register.

The stack registers are not memory.

> Please find the following RTL Dump of the fdivrs instruction generated. 
> It clearly access the memory for read access! 

That is a constant read, that doesn't count either.  It is in memory only 
because the instruction doesn't support constant immediates, the memory is 
read-only.

Jakub