Intrinsics __readeflags and __writeeflags

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Intrinsics __readeflags and __writeeflags

Alexey Volkov
Hello all,

I am trying to implement intrinsics __readeflags and __writeeflags reading and writing EFLAGS register on x86.
These intrinsics expand to two instructions popf and push to register for __readeflags and pushf and pop to register for __writeeflags.
These instructions are not connected explicitly so I can't use patterns in .td file to match intrinsics.

I tried to implement custom expansion making COPY DAG node with copy from EFLAGS to register.
But this solution works only at -O0 level and failed at -O1 and higher: the problem is that Post-RA pseudo instruction expansion pass seems to be called only at -O0.

Another way is to expand intrinsics to DAG nodes for each PUSH, POP, PUSHF and POPF instructions.
This will add 4 new X86ISD types for DAG nodes for these instructions.

What is the proper way to expand these intrinsics?

--
Alexey Volkov
Intel Corporation

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

Reid Kleckner-2
I don't know enough about LLVM CodeGen to answer your questions.  I'm just curious.

What is the intended level of support for these intrinsics?  Are they for reading ALU flags like CF, OF, etc, or for seldom changed control flags like TF and AC?  Even DF is typically scratch, and could be used for an -Oz memmove lowering for example.

I don't think LLVM will ever really support capturing ALU flags from previous ops without "using" the operation.  LLVM does have overflow intrinsics though:


On Tue, Dec 17, 2013 at 1:02 AM, Alexey Volkov <[hidden email]> wrote:
Hello all,

I am trying to implement intrinsics __readeflags and __writeeflags reading and writing EFLAGS register on x86.
These intrinsics expand to two instructions popf and push to register for __readeflags and pushf and pop to register for __writeeflags.
These instructions are not connected explicitly so I can't use patterns in .td file to match intrinsics.

I tried to implement custom expansion making COPY DAG node with copy from EFLAGS to register.
But this solution works only at -O0 level and failed at -O1 and higher: the problem is that Post-RA pseudo instruction expansion pass seems to be called only at -O0.

Another way is to expand intrinsics to DAG nodes for each PUSH, POP, PUSHF and POPF instructions.
This will add 4 new X86ISD types for DAG nodes for these instructions.

What is the proper way to expand these intrinsics?

--
Alexey Volkov
Intel Corporation

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

David Majnemer
This intrinsic seems very ill-defined, apparently it can be freely reordered and does _not_ act like a compiler barrier. [1]
Other than source compatibility, why would one want this intrinsic?  What semantics is it supposed to give?



On Tue, Dec 17, 2013 at 11:00 AM, Reid Kleckner <[hidden email]> wrote:
I don't know enough about LLVM CodeGen to answer your questions.  I'm just curious.

What is the intended level of support for these intrinsics?  Are they for reading ALU flags like CF, OF, etc, or for seldom changed control flags like TF and AC?  Even DF is typically scratch, and could be used for an -Oz memmove lowering for example.

I don't think LLVM will ever really support capturing ALU flags from previous ops without "using" the operation.  LLVM does have overflow intrinsics though:


On Tue, Dec 17, 2013 at 1:02 AM, Alexey Volkov <[hidden email]> wrote:
Hello all,

I am trying to implement intrinsics __readeflags and __writeeflags reading and writing EFLAGS register on x86.
These intrinsics expand to two instructions popf and push to register for __readeflags and pushf and pop to register for __writeeflags.
These instructions are not connected explicitly so I can't use patterns in .td file to match intrinsics.

I tried to implement custom expansion making COPY DAG node with copy from EFLAGS to register.
But this solution works only at -O0 level and failed at -O1 and higher: the problem is that Post-RA pseudo instruction expansion pass seems to be called only at -O0.

Another way is to expand intrinsics to DAG nodes for each PUSH, POP, PUSHF and POPF instructions.
This will add 4 new X86ISD types for DAG nodes for these instructions.

What is the proper way to expand these intrinsics?

--
Alexey Volkov
Intel Corporation

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

Joerg Sonnenberger
On Tue, Dec 17, 2013 at 01:05:10PM -0800, David Majnemer wrote:
> This intrinsic seems very ill-defined, apparently it can be freely
> reordered and does _not_ act like a compiler barrier. [1]
> Other than source compatibility, why would one want this intrinsic?  What
> semantics is it supposed to give?

Even more, why can't it just be defined as inline function in some
header?

Joerg
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

Alexey Volkov
These intrinsics are introduced for compatibility purposes.
Besides MSVC GCC also supports it in its main trunk; ICC supports it on Windows and is going to support in the next version on Linux. 

2013/12/18 Joerg Sonnenberger <[hidden email]>
On Tue, Dec 17, 2013 at 01:05:10PM -0800, David Majnemer wrote:
> This intrinsic seems very ill-defined, apparently it can be freely
> reordered and does _not_ act like a compiler barrier. [1]
> Other than source compatibility, why would one want this intrinsic?  What
> semantics is it supposed to give?

Even more, why can't it just be defined as inline function in some
header?
Does it mean that I can use inline assembler instead of implementing compiler intrinsic? 

Joerg
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



--
Alexey Volkov
Intel Corporation

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

David Chisnall-5
On 18 Dec 2013, at 11:03, Alexey Volkov <[hidden email]> wrote:

> These intrinsics are introduced for compatibility purposes.
> Besides MSVC GCC also supports it in its main trunk; ICC supports it on Windows and is going to support in the next version on Linux.

There have been two questions, neither of which is really answered.  The questions are:

- Why does this need to be an LLVM intrinsic, rather than an inline function in a clang header expanding to some inline asm?

- Given that this instruction has such poorly defined semantics that it effectively returns an arbitrary number in any function that does arithmetic, what possible benefit is there in providing it as an LLVM intrinsic?

David


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Intrinsics __readeflags and __writeeflags

Alexey Volkov
I don't insist on implementing LLVM intrinsic, clang header with inline asm should be enough and is much easier to implement.
I am just looking for the best way to introduce this functionality to LLVM.
I understand the problem with arbitrary results in some cases. Again, the main benefit here is compatibility with other compilers.

Alexey.

2013/12/18 David Chisnall <[hidden email]>
On 18 Dec 2013, at 11:03, Alexey Volkov <[hidden email]> wrote:

> These intrinsics are introduced for compatibility purposes.
> Besides MSVC GCC also supports it in its main trunk; ICC supports it on Windows and is going to support in the next version on Linux.

There have been two questions, neither of which is really answered.  The questions are:

- Why does this need to be an LLVM intrinsic, rather than an inline function in a clang header expanding to some inline asm?

- Given that this instruction has such poorly defined semantics that it effectively returns an arbitrary number in any function that does arithmetic, what possible benefit is there in providing it as an LLVM intrinsic?

David




--
Alexey Volkov
Intel Corporation

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev