summaryrefslogtreecommitdiff
path: root/test/CodeGen/AArch64/GlobalISel/legalize-inserts.mir
blob: 7432b6761b73e820676a65bda00da2911ede30dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# RUN: llc -O0 -run-pass=legalizer -global-isel %s -o - | FileCheck %s

--- |
  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
  target triple = "aarch64--"
  define void @test_inserts_1() { ret void }
  define void @test_inserts_2() { ret void }
  define void @test_inserts_3() { ret void }
  define void @test_inserts_4() { ret void }
  define void @test_inserts_5() { ret void }
  define void @test_inserts_6() { ret void }
...

---
name:            test_inserts_1
body: |
  bb.0:
    liveins: %w0

      ; Low part of insertion wipes out the old register entirely, so %0 gets
      ; forwarded to the G_STORE. Hi part is unchanged so (split) G_LOAD gets
      ; forwarded.
    ; CHECK-LABEL: name: test_inserts_1
    ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: G_STORE %0(s64)
    ; CHECK: G_STORE [[HI]]
    %0:_(s64) = COPY %x0
    %1:_(s32) = COPY %w1
    %2:_(p0) = COPY %x2
    %3:_(s128) = G_LOAD %2(p0) :: (load 16)
    %4:_(s128) = G_INSERT %3(s128), %0(s64), 0
    G_STORE %4(s128), %2(p0) :: (store 16)
    RET_ReallyLR
...

---
name:            test_inserts_2
body: |
  bb.0:
    liveins: %w0

      ; Low insertion wipes out the old register entirely, so %0 gets forwarded
      ; to the G_STORE again. Second insertion is real.
    ; CHECK-LABEL: name: test_inserts_2
    ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: [[NEWHI:%[0-9]+]]:_(s64) = G_INSERT [[HI]], %1(s32), 0
    ; CHECK: G_STORE %0(s64)
    ; CHECK: G_STORE [[NEWHI]]
    %0:_(s64) = COPY %x0
    %1:_(s32) = COPY %w1
    %2:_(p0) = COPY %x2
    %3:_(s128) = G_LOAD %2(p0) :: (load 16)
    %4:_(s128) = G_INSERT %3(s128), %0(s64), 0
    %5:_(s128) = G_INSERT %4(s128), %1(s32), 64
    G_STORE %5(s128), %2(p0) :: (store 16)
    RET_ReallyLR
...

---
name:            test_inserts_3
body: |
  bb.0:
    liveins: %w0

      ; I'm not entirely convinced inserting a p0 into an s64 is valid, but it's
      ; certainly better than the alternative of directly forwarding the value
      ; which would cause a nasty type mismatch.
    ; CHECK-LABEL: name: test_inserts_3
    ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
    ; CHECK: [[NEWLO:%[0-9]+]]:_(s64) = G_PTRTOINT %0(p0)
    ; CHECK: G_STORE [[NEWLO]](s64)
    ; CHECK: G_STORE [[HI]]
    %0:_(p0) = COPY %x0
    %1:_(s32) = COPY %w1
    %2:_(p0) = COPY %x2
    %3:_(s128) = G_LOAD %2(p0) :: (load 16)
    %4:_(s128) = G_INSERT %3(s128), %0(p0), 0
    G_STORE %4(s128), %2(p0) :: (store 16)
    RET_ReallyLR
...

---
name:            test_inserts_4
body: |
  bb.0:
    liveins: %w0

      ; A narrow insert gets surrounded by a G_ANYEXT/G_TRUNC pair.
    ; CHECK-LABEL: name: test_inserts_4
    ; CHECK: [[VALEXT:%[0-9]+]]:_(s32) = COPY %2(s32)
    ; CHECK: [[VAL:%[0-9]+]]:_(s32) = G_INSERT [[VALEXT]], %1(s1), 0
    ; CHECK: %5:_(s8) = G_TRUNC [[VAL]](s32)
    %4:_(s32) = COPY %w0
    %0:_(s1) = G_TRUNC %4
    %5:_(s32) = COPY %w1
    %1:_(s8) = G_TRUNC %5
    %2:_(p0) = COPY %x2
    %3:_(s8) = G_INSERT %1(s8), %0(s1), 0
    G_STORE %3(s8), %2(p0) :: (store 1)
    RET_ReallyLR
...

---
name:            test_inserts_5
body: |
  bb.0:
    liveins: %x0, %x1, %x2


    ; CHECK-LABEL: name: test_inserts_5
    ; CHECK: [[INS_LO:%[0-9]+]]:_(s32) = G_EXTRACT %2(s64), 0
    ; CHECK: [[VAL_LO:%[0-9]+]]:_(s64) = G_INSERT %0, [[INS_LO]](s32), 32
    ; CHECK: [[INS_HI:%[0-9]+]]:_(s32) = G_EXTRACT %2(s64), 32
    ; CHECK: [[VAL_HI:%[0-9]+]]:_(s64) = G_INSERT %1, [[INS_HI]](s32), 0
    ; CHECK: %4:_(s128) = G_MERGE_VALUES [[VAL_LO]](s64), [[VAL_HI]](s64)
    %0:_(s64) = COPY %x0
    %1:_(s64) = COPY %x1
    %2:_(s64) = COPY %x2
    %3:_(s128) = G_MERGE_VALUES %0, %1
    %4:_(s128) = G_INSERT %3, %2, 32
    RET_ReallyLR
...

---
name:            test_inserts_6
body: |
  bb.0:
    liveins: %x0, %x1, %x2


    ; CHECK-LABEL: name: test_inserts_6
    ; CHECK: [[VAL_LO:%[0-9]+]]:_(s64) = G_INSERT %0, %2(s32), 32
    ; CHECK: %4:_(s128) = G_MERGE_VALUES [[VAL_LO]](s64), %1(s64)
    %0:_(s64) = COPY %x0
    %1:_(s64) = COPY %x1
    %2:_(s32) = COPY %w2
    %3:_(s128) = G_MERGE_VALUES %0, %1
    %4:_(s128) = G_INSERT %3, %2, 32
    RET_ReallyLR
...