Adding an intrinsic to read the stack pointer, e.g., RSP in x86

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Adding an intrinsic to read the stack pointer, e.g., RSP in x86

Alex Denisov via cfe-dev
I need to use the stack pointer, e.g., RSP on X86, to get some
information off the stack.  I am not sure what the best way to do this is.

My plan was to create an intrinsic, e.g., 

  let TargetPrefix = "x86" in {
     def int_x86_read_sp : GCCBuiltin<"__builtin_read_sp">, 
      Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
  }
  
I thought I would define a PseudoI, e.g., 

  let Uses = [RSP] in
      def READSP64 : PseudoI<(outs GR64:$dst), (ins),
            [(set GR64:$dst, RSP)]>,
                Requires<[In64BitMode]>;
But, actually I am not sure how this would come into play.  (Do I need this?  If so, how do I use it?)

To test it out I added a Builtin to BuiltinsX86.def, e.g.,

  BUILTIN(__builtin_read_sp, "ULLi", "")
  
When I try and compile, I get a proper .ll file from clang with the instruction

    %0 = call i64 @llvm.x86.read.sp()

However, it fails, with 

llc: ./llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

I am not sure how to introduce the IR to read the RSP so I can create
code to do a calculation on the RSP to retrieve a value buried in the
stack.  I figure I need to lower the `call i64 @llvm.x86.read.sp` in
X86TargetLowering::LowerOperation.  I am not sure if this would be
ISD::INTRINSIC_WO_CHAIN or ISD::INTRINSIC_W_CHAIN (and I don't
actually understand what would go in the intrinsic definition to make
it one or the other.  Any pointers would be appreciated.  Thanks,

seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
412-268-3828

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic to read the stack pointer, e.g., RSP in x86

Alex Denisov via cfe-dev
I believe clang does support getting the stack-pointer via the "gcc register variable extension". The syntax and behaviour would follow this:
https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html#Global-Register-Variables

however, it is restricted specifically to the stack-pointer.

#include <stdio.h>

register size_t stack asm("rsp");

int main()
{
    printf("%zx\n", stack);
}

It compiles to this LLVM IR:
define i32 @main() #0 {
entry:
  %0 = call i64 @llvm.read_register.i64(metadata !0)
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), i64 %0)
  ret i32 0
}

--
Mats



On 11 December 2017 at 02:58, Seth Goldstein via cfe-dev <[hidden email]> wrote:
I need to use the stack pointer, e.g., RSP on X86, to get some
information off the stack.  I am not sure what the best way to do this is.

My plan was to create an intrinsic, e.g., 

  let TargetPrefix = "x86" in {
     def int_x86_read_sp : GCCBuiltin<"__builtin_read_sp">, 
      Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
  }
  
I thought I would define a PseudoI, e.g., 

  let Uses = [RSP] in
      def READSP64 : PseudoI<(outs GR64:$dst), (ins),
            [(set GR64:$dst, RSP)]>,
                Requires<[In64BitMode]>;
But, actually I am not sure how this would come into play.  (Do I need this?  If so, how do I use it?)

To test it out I added a Builtin to BuiltinsX86.def, e.g.,

  BUILTIN(__builtin_read_sp, "ULLi", "")
  
When I try and compile, I get a proper .ll file from clang with the instruction

    %0 = call i64 @llvm.x86.read.sp()

However, it fails, with 

llc: ./llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

I am not sure how to introduce the IR to read the RSP so I can create
code to do a calculation on the RSP to retrieve a value buried in the
stack.  I figure I need to lower the `call i64 @llvm.x86.read.sp` in
X86TargetLowering::LowerOperation.  I am not sure if this would be
ISD::INTRINSIC_WO_CHAIN or ISD::INTRINSIC_W_CHAIN (and I don't
actually understand what would go in the intrinsic definition to make
it one or the other.  Any pointers would be appreciated.  Thanks,

seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
<a href="tel:(412)%20268-3828" value="+14122683828" target="_blank">412-268-3828

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic to read the stack pointer, e.g., RSP in x86

Alex Denisov via cfe-dev
In reply to this post by Alex Denisov via cfe-dev
On 12/10/17 9:58 PM, Seth Goldstein via cfe-dev wrote:
I need to use the stack pointer, e.g., RSP on X86, to get some
information off the stack.  I am not sure what the best way to do this is.

Is there a reason that you cannot insert some inline assembly code to read the stack pointer?  The only downside to it (as far as I can tell) is that you would need to have different assembly code for each platform on which you want to do this.

Regards,

John Criswell

My plan was to create an intrinsic, e.g., 

  let TargetPrefix = "x86" in {
     def int_x86_read_sp : GCCBuiltin<"__builtin_read_sp">, 
      Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
  }
  
I thought I would define a PseudoI, e.g., 

  let Uses = [RSP] in
      def READSP64 : PseudoI<(outs GR64:$dst), (ins),
            [(set GR64:$dst, RSP)]>,
                Requires<[In64BitMode]>;
But, actually I am not sure how this would come into play.  (Do I need this?  If so, how do I use it?)

To test it out I added a Builtin to BuiltinsX86.def, e.g.,

  BUILTIN(__builtin_read_sp, "ULLi", "")
  
When I try and compile, I get a proper .ll file from clang with the instruction

    %0 = call i64 @llvm.x86.read.sp()

However, it fails, with 

llc: ./llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

I am not sure how to introduce the IR to read the RSP so I can create
code to do a calculation on the RSP to retrieve a value buried in the
stack.  I figure I need to lower the `call i64 @llvm.x86.read.sp` in
X86TargetLowering::LowerOperation.  I am not sure if this would be
ISD::INTRINSIC_WO_CHAIN or ISD::INTRINSIC_W_CHAIN (and I don't
actually understand what would go in the intrinsic definition to make
it one or the other.  Any pointers would be appreciated.  Thanks,

seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
412-268-3828


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic to read the stack pointer, e.g., RSP in x86

Alex Denisov via cfe-dev
The issue is that I need to insert this code as part of a transformation.  Is there a way to insert assembly code in a pass?

-seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
412-268-3828

On Mon, Dec 11, 2017 at 10:51 AM, John Criswell <[hidden email]> wrote:
On 12/10/17 9:58 PM, Seth Goldstein via cfe-dev wrote:
I need to use the stack pointer, e.g., RSP on X86, to get some
information off the stack.  I am not sure what the best way to do this is.

Is there a reason that you cannot insert some inline assembly code to read the stack pointer?  The only downside to it (as far as I can tell) is that you would need to have different assembly code for each platform on which you want to do this.

Regards,

John Criswell

My plan was to create an intrinsic, e.g., 

  let TargetPrefix = "x86" in {
     def int_x86_read_sp : GCCBuiltin<"__builtin_read_sp">, 
      Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
  }
  
I thought I would define a PseudoI, e.g., 

  let Uses = [RSP] in
      def READSP64 : PseudoI<(outs GR64:$dst), (ins),
            [(set GR64:$dst, RSP)]>,
                Requires<[In64BitMode]>;
But, actually I am not sure how this would come into play.  (Do I need this?  If so, how do I use it?)

To test it out I added a Builtin to BuiltinsX86.def, e.g.,

  BUILTIN(__builtin_read_sp, "ULLi", "")
  
When I try and compile, I get a proper .ll file from clang with the instruction

    %0 = call i64 @llvm.x86.read.sp()

However, it fails, with 

llc: ./llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

I am not sure how to introduce the IR to read the RSP so I can create
code to do a calculation on the RSP to retrieve a value buried in the
stack.  I figure I need to lower the `call i64 @llvm.x86.read.sp` in
X86TargetLowering::LowerOperation.  I am not sure if this would be
ISD::INTRINSIC_WO_CHAIN or ISD::INTRINSIC_W_CHAIN (and I don't
actually understand what would go in the intrinsic definition to make
it one or the other.  Any pointers would be appreciated.  Thanks,

seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
<a href="tel:(412)%20268-3828" value="+14122683828" target="_blank">412-268-3828


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic to read the stack pointer, e.g., RSP in x86

Alex Denisov via cfe-dev
On 12/11/17 11:10 AM, Seth Goldstein wrote:
The issue is that I need to insert this code as part of a transformation.  Is there a way to insert assembly code in a pass?

Yes.

You can create an inline assembly code "value" by creating an InlineAsm object.  You then make that "value" an argument to an LLVM CallInst object.

For more information, look at the InlineAsm and CallInst classes in the LLVM Doxygen documentation.

Regards,

John Criswell


-seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
412-268-3828

On Mon, Dec 11, 2017 at 10:51 AM, John Criswell <[hidden email]> wrote:
On 12/10/17 9:58 PM, Seth Goldstein via cfe-dev wrote:
I need to use the stack pointer, e.g., RSP on X86, to get some
information off the stack.  I am not sure what the best way to do this is.

Is there a reason that you cannot insert some inline assembly code to read the stack pointer?  The only downside to it (as far as I can tell) is that you would need to have different assembly code for each platform on which you want to do this.

Regards,

John Criswell

My plan was to create an intrinsic, e.g., 

  let TargetPrefix = "x86" in {
     def int_x86_read_sp : GCCBuiltin<"__builtin_read_sp">, 
      Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
  }
  
I thought I would define a PseudoI, e.g., 

  let Uses = [RSP] in
      def READSP64 : PseudoI<(outs GR64:$dst), (ins),
            [(set GR64:$dst, RSP)]>,
                Requires<[In64BitMode]>;
But, actually I am not sure how this would come into play.  (Do I need this?  If so, how do I use it?)

To test it out I added a Builtin to BuiltinsX86.def, e.g.,

  BUILTIN(__builtin_read_sp, "ULLi", "")
  
When I try and compile, I get a proper .ll file from clang with the instruction

    %0 = call i64 @llvm.x86.read.sp()

However, it fails, with 

llc: ./llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

I am not sure how to introduce the IR to read the RSP so I can create
code to do a calculation on the RSP to retrieve a value buried in the
stack.  I figure I need to lower the `call i64 @llvm.x86.read.sp` in
X86TargetLowering::LowerOperation.  I am not sure if this would be
ISD::INTRINSIC_WO_CHAIN or ISD::INTRINSIC_W_CHAIN (and I don't
actually understand what would go in the intrinsic definition to make
it one or the other.  Any pointers would be appreciated.  Thanks,

seth


--------------
Seth Copen Goldstein
Carnegie Mellon University
Computer Science Dept
7111 GHC
<a moz-do-not-send="true" href="tel:%28412%29%20268-3828" value="+14122683828" target="_blank">412-268-3828


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell

-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev