[GlobalISel][X86] G_LOAD/G_STORE pointer selection support.
authorIgor Breger <igor.breger@intel.com>
Mon, 1 May 2017 06:08:32 +0000 (06:08 +0000)
committerIgor Breger <igor.breger@intel.com>
Mon, 1 May 2017 06:08:32 +0000 (06:08 +0000)
Summary: [GlobalISel][X86] G_LOAD/G_STORE pointer selection support.

Reviewers: zvi, guyblank

Reviewed By: zvi, guyblank

Subscribers: dberris, rovka, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D32217

llvm-svn: 301788

llvm/lib/Target/X86/X86InstructionSelector.cpp
llvm/test/CodeGen/X86/GlobalISel/memop-x32.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/GlobalISel/memop.ll
llvm/test/CodeGen/X86/GlobalISel/select-memop-x32.mir [new file with mode: 0644]
llvm/test/CodeGen/X86/GlobalISel/select-memop.mir

index 3457d35..60aefaf 100644 (file)
@@ -400,7 +400,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB,
   } else if (Ty == LLT::scalar(16)) {
     if (X86::GPRRegBankID == RB.getID())
       return Isload ? X86::MOV16rm : X86::MOV16mr;
-  } else if (Ty == LLT::scalar(32)) {
+  } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
     if (X86::GPRRegBankID == RB.getID())
       return Isload ? X86::MOV32rm : X86::MOV32mr;
     if (X86::VECRRegBankID == RB.getID())
@@ -408,7 +408,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB,
                                  : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
                     : (HasAVX512 ? X86::VMOVSSZmr
                                  : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
-  } else if (Ty == LLT::scalar(64)) {
+  } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
     if (X86::GPRRegBankID == RB.getID())
       return Isload ? X86::MOV64rm : X86::MOV64mr;
     if (X86::VECRRegBankID == RB.getID())
diff --git a/llvm/test/CodeGen/X86/GlobalISel/memop-x32.ll b/llvm/test/CodeGen/X86/GlobalISel/memop-x32.ll
new file mode 100644 (file)
index 0000000..49a7fd7
--- /dev/null
@@ -0,0 +1,101 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=i386-linux-gnu                       -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE_FAST
+; RUN: llc -mtriple=i386-linux-gnu -regbankselect-greedy -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE_GREEDY
+
+;TODO merge with x86-64 tests (many operations not suppored yet)
+
+define i8 @test_load_i8(i8 * %p1) {
+; ALL-LABEL: test_load_i8:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movb (%eax), %al
+; ALL-NEXT:    retl
+  %r = load i8, i8* %p1
+  ret i8 %r
+}
+
+define i16 @test_load_i16(i16 * %p1) {
+; ALL-LABEL: test_load_i16:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movzwl (%eax), %eax
+; ALL-NEXT:    retl
+  %r = load i16, i16* %p1
+  ret i16 %r
+}
+
+define i32 @test_load_i32(i32 * %p1) {
+; ALL-LABEL: test_load_i32:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    retl
+  %r = load i32, i32* %p1
+  ret i32 %r
+}
+
+define i8 * @test_store_i8(i8 %val, i8 * %p1) {
+; ALL-LABEL: test_store_i8:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movb (%eax), %cl
+; ALL-NEXT:    leal 8(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movb %cl, (%eax)
+; ALL-NEXT:    retl
+  store i8 %val, i8* %p1
+  ret i8 * %p1;
+}
+
+define i16 * @test_store_i16(i16 %val, i16 * %p1) {
+; ALL-LABEL: test_store_i16:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movzwl (%eax), %ecx
+; ALL-NEXT:    leal 8(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movw %cx, (%eax)
+; ALL-NEXT:    retl
+  store i16 %val, i16* %p1
+  ret i16 * %p1;
+}
+
+define i32 * @test_store_i32(i32 %val, i32 * %p1) {
+; ALL-LABEL: test_store_i32:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %ecx
+; ALL-NEXT:    leal 8(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movl %ecx, (%eax)
+; ALL-NEXT:    retl
+  store i32 %val, i32* %p1
+  ret i32 * %p1;
+}
+
+define i32* @test_load_ptr(i32** %ptr1) {
+; ALL-LABEL: test_load_ptr:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    retl
+  %p = load i32*, i32** %ptr1
+  ret i32* %p
+}
+
+define void @test_store_ptr(i32** %ptr1, i32* %a) {
+; ALL-LABEL: test_store_ptr:
+; ALL:       # BB#0:
+; ALL-NEXT:    leal 4(%esp), %eax
+; ALL-NEXT:    movl (%eax), %eax
+; ALL-NEXT:    leal 8(%esp), %ecx
+; ALL-NEXT:    movl (%ecx), %ecx
+; ALL-NEXT:    movl %ecx, (%eax)
+; ALL-NEXT:    retl
+  store i32* %a, i32** %ptr1
+  ret void
+}
index f793e36..a7407c0 100644 (file)
@@ -187,3 +187,20 @@ define double * @test_store_double(double %val, double * %p1) {
   ret double * %p1;
 }
 
+define i32* @test_load_ptr(i32** %ptr1) {
+; ALL-LABEL: test_load_ptr:
+; ALL:       # BB#0:
+; ALL-NEXT:    movq (%rdi), %rax
+; ALL-NEXT:    retq
+  %p = load i32*, i32** %ptr1
+  ret i32* %p
+}
+
+define void @test_store_ptr(i32** %ptr1, i32* %a) {
+; ALL-LABEL: test_store_ptr:
+; ALL:       # BB#0:
+; ALL-NEXT:    movq %rsi, (%rdi)
+; ALL-NEXT:    retq
+  store i32* %a, i32** %ptr1
+  ret void
+}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/select-memop-x32.mir b/llvm/test/CodeGen/X86/GlobalISel/select-memop-x32.mir
new file mode 100644 (file)
index 0000000..8e6a277
--- /dev/null
@@ -0,0 +1,310 @@
+# RUN: llc -mtriple=i386-linux-gnu  -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL
+
+--- |
+  define i8 @test_load_i8(i8* %p1) {
+    %r = load i8, i8* %p1
+    ret i8 %r
+  }
+
+  define i16 @test_load_i16(i16* %p1) {
+    %r = load i16, i16* %p1
+    ret i16 %r
+  }
+
+  define i32 @test_load_i32(i32* %p1) {
+    %r = load i32, i32* %p1
+    ret i32 %r
+  }
+
+  define i8* @test_store_i8(i8 %val, i8* %p1) {
+    store i8 %val, i8* %p1
+    ret i8* %p1
+  }
+
+  define i16* @test_store_i16(i16 %val, i16* %p1) {
+    store i16 %val, i16* %p1
+    ret i16* %p1
+  }
+
+  define i32* @test_store_i32(i32 %val, i32* %p1) {
+    store i32 %val, i32* %p1
+    ret i32* %p1
+  }
+
+  define i32* @test_load_ptr(i32** %ptr1) {
+    %p = load i32*, i32** %ptr1
+    ret i32* %p
+  }
+
+  define void @test_store_ptr(i32** %ptr1, i32* %a) {
+    store i32* %a, i32** %ptr1
+    ret void
+  }
+
+...
+---
+name:            test_load_i8
+# ALL-LABEL: name:  test_load_i8
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr8 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+fixedStack:
+  - { id: 0, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %1 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %1, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %2 = MOV8rm %0, 1, _, 0, _ :: (load 1 from %ir.p1)
+# ALL-NEXT:     %al = COPY %2
+# ALL-NEXT:     RET 0, implicit %al
+body:             |
+  bb.1 (%ir-block.0):
+    %1(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0(p0) = G_LOAD %1(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    %2(s8) = G_LOAD %0(p0) :: (load 1 from %ir.p1)
+    %al = COPY %2(s8)
+    RET 0, implicit %al
+
+...
+---
+name:            test_load_i16
+# ALL-LABEL: name:  test_load_i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr16 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+fixedStack:
+  - { id: 0, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %1 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %1, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %2 = MOV16rm %0, 1, _, 0, _ :: (load 2 from %ir.p1)
+# ALL-NEXT:     %ax = COPY %2
+# ALL-NEXT:     RET 0, implicit %ax
+body:             |
+  bb.1 (%ir-block.0):
+    %1(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0(p0) = G_LOAD %1(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    %2(s16) = G_LOAD %0(p0) :: (load 2 from %ir.p1)
+    %ax = COPY %2(s16)
+    RET 0, implicit %ax
+
+...
+---
+name:            test_load_i32
+# ALL-LABEL: name:  test_load_i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+fixedStack:
+  - { id: 0, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %1 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %1, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %2 = MOV32rm %0, 1, _, 0, _ :: (load 4 from %ir.p1)
+# ALL-NEXT:     %eax = COPY %2
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    %1(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0(p0) = G_LOAD %1(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    %2(s32) = G_LOAD %0(p0) :: (load 4 from %ir.p1)
+    %eax = COPY %2(s32)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_store_i8
+# ALL-LABEL: name:  test_store_i8
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr8 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+# ALL-NEXT:   - { id: 3, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+fixedStack:
+  - { id: 0, offset: 4, size: 4, alignment: 4, isImmutable: true, isAliased: false }
+  - { id: 1, offset: 0, size: 1, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %2 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV8rm %2, 1, _, 0, _ :: (invariant load 1 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %3 = LEA32r %fixed-stack.1, 1, _, 0, _
+# ALL-NEXT:     %1 = MOV32rm %3, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.1, align 0)
+# ALL-NEXT:     MOV8mr %1, 1, _, 0, _, %0 :: (store 1 into %ir.p1)
+# ALL-NEXT:     %eax = COPY %1
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    %2(p0) = G_FRAME_INDEX %fixed-stack.1
+    %0(s8) = G_LOAD %2(p0) :: (invariant load 1 from %fixed-stack.1, align 0)
+    %3(p0) = G_FRAME_INDEX %fixed-stack.0
+    %1(p0) = G_LOAD %3(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    G_STORE %0(s8), %1(p0) :: (store 1 into %ir.p1)
+    %eax = COPY %1(p0)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_store_i16
+# ALL-LABEL: name:  test_store_i16
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr16 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+# ALL-NEXT:   - { id: 3, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+fixedStack:
+  - { id: 0, offset: 4, size: 4, alignment: 4, isImmutable: true, isAliased: false }
+  - { id: 1, offset: 0, size: 2, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %2 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV16rm %2, 1, _, 0, _ :: (invariant load 2 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %3 = LEA32r %fixed-stack.1, 1, _, 0, _
+# ALL-NEXT:     %1 = MOV32rm %3, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.1, align 0)
+# ALL-NEXT:     MOV16mr %1, 1, _, 0, _, %0 :: (store 2 into %ir.p1)
+# ALL-NEXT:     %eax = COPY %1
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    %2(p0) = G_FRAME_INDEX %fixed-stack.1
+    %0(s16) = G_LOAD %2(p0) :: (invariant load 2 from %fixed-stack.1, align 0)
+    %3(p0) = G_FRAME_INDEX %fixed-stack.0
+    %1(p0) = G_LOAD %3(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p1)
+    %eax = COPY %1(p0)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_store_i32
+# ALL-LABEL: name:  test_store_i32
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+# ALL-NEXT:   - { id: 3, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+fixedStack:
+  - { id: 0, offset: 4, size: 4, alignment: 4, isImmutable: true, isAliased: false }
+  - { id: 1, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %2 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %2, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %3 = LEA32r %fixed-stack.1, 1, _, 0, _
+# ALL-NEXT:     %1 = MOV32rm %3, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.1, align 0)
+# ALL-NEXT:     MOV32mr %1, 1, _, 0, _, %0 :: (store 4 into %ir.p1)
+# ALL-NEXT:     %eax = COPY %1
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    %2(p0) = G_FRAME_INDEX %fixed-stack.1
+    %0(s32) = G_LOAD %2(p0) :: (invariant load 4 from %fixed-stack.1, align 0)
+    %3(p0) = G_FRAME_INDEX %fixed-stack.0
+    %1(p0) = G_LOAD %3(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    G_STORE %0(s32), %1(p0) :: (store 4 into %ir.p1)
+    %eax = COPY %1(p0)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_load_ptr
+# ALL-LABEL: name:  test_load_ptr
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+fixedStack:
+  - { id: 0, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %1 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %1, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %2 = MOV32rm %0, 1, _, 0, _ :: (load 4 from %ir.ptr1)
+# ALL-NEXT:     %eax = COPY %2
+# ALL-NEXT:     RET 0, implicit %eax
+body:             |
+  bb.1 (%ir-block.0):
+    %1(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0(p0) = G_LOAD %1(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    %2(p0) = G_LOAD %0(p0) :: (load 4 from %ir.ptr1)
+    %eax = COPY %2(p0)
+    RET 0, implicit %eax
+
+...
+---
+name:            test_store_ptr
+# ALL-LABEL: name:  test_store_ptr
+alignment:       4
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:   - { id: 0, class: gr32 }
+# ALL-NEXT:   - { id: 1, class: gr32 }
+# ALL-NEXT:   - { id: 2, class: gr32 }
+# ALL-NEXT:   - { id: 3, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+  - { id: 3, class: gpr }
+fixedStack:
+  - { id: 0, offset: 4, size: 4, alignment: 4, isImmutable: true, isAliased: false }
+  - { id: 1, offset: 0, size: 4, alignment: 16, isImmutable: true, isAliased: false }
+# ALL:          %2 = LEA32r %fixed-stack.0, 1, _, 0, _
+# ALL-NEXT:     %0 = MOV32rm %2, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.0, align 0)
+# ALL-NEXT:     %3 = LEA32r %fixed-stack.1, 1, _, 0, _
+# ALL-NEXT:     %1 = MOV32rm %3, 1, _, 0, _ :: (invariant load 4 from %fixed-stack.1, align 0)
+# ALL-NEXT:     MOV32mr %0, 1, _, 0, _, %1 :: (store 4 into %ir.ptr1)
+# ALL-NEXT:     RET 0
+body:             |
+  bb.1 (%ir-block.0):
+    %2(p0) = G_FRAME_INDEX %fixed-stack.1
+    %0(p0) = G_LOAD %2(p0) :: (invariant load 4 from %fixed-stack.1, align 0)
+    %3(p0) = G_FRAME_INDEX %fixed-stack.0
+    %1(p0) = G_LOAD %3(p0) :: (invariant load 4 from %fixed-stack.0, align 0)
+    G_STORE %1(p0), %0(p0) :: (store 4 into %ir.ptr1)
+    RET 0
+
+...
index 943c9ac..817dc3c 100644 (file)
     ret <4 x i32>* %p1
   }
 
+  define i32* @test_load_ptr(i32** %ptr1) {
+    %p = load i32*, i32** %ptr1
+    ret i32* %p
+  }
+
+  define void @test_store_ptr(i32** %ptr1, i32* %a) {
+    store i32* %a, i32** %ptr1
+    ret void
+  }
 ...
 ---
 # ALL-LABEL: name:            test_load_i8
@@ -580,3 +589,49 @@ body:             |
     RET 0, implicit %rax
 
 ...
+---
+# ALL-LABEL: name:            test_load_ptr
+name:            test_load_ptr
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+registers:
+# ALL:   - { id: 0, class: gr64 }
+# ALL:   - { id: 1, class: gr64 }
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# ALL: %1 = MOV64rm %0, 1, _, 0, _ :: (load 8 from %ir.ptr1)
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi
+
+    %0(p0) = COPY %rdi
+    %1(p0) = G_LOAD %0(p0) :: (load 8 from %ir.ptr1)
+    %rax = COPY %1(p0)
+    RET 0, implicit %rax
+
+...
+---
+# ALL-LABEL: name:            test_store_ptr
+name:            test_store_ptr
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+registers:
+# ALL:   - { id: 0, class: gr64 }
+# ALL:   - { id: 1, class: gr64 }
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# ALL: MOV64mr %0, 1, _, 0, _, %1 :: (store 8 into %ir.ptr1)
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi, %rsi
+
+    %0(p0) = COPY %rdi
+    %1(p0) = COPY %rsi
+    G_STORE %1(p0), %0(p0) :: (store 8 into %ir.ptr1)
+    RET 0
+
+...