1 # RUN: llc -O0 -run-pass=legalizer %s -o - | FileCheck %s
4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64--"
6 define void @test_inserts_1() { ret void }
7 define void @test_inserts_2() { ret void }
8 define void @test_inserts_3() { ret void }
9 define void @test_inserts_4() { ret void }
10 define void @test_inserts_5() { ret void }
11 define void @test_inserts_6() { ret void }
12 define void @test_inserts_nonpow2() { ret void }
21 ; Low part of insertion wipes out the old register entirely, so %0 gets
22 ; forwarded to the G_STORE. Hi part is unchanged so (split) G_LOAD gets
24 ; CHECK-LABEL: name: test_inserts_1
25 ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
26 ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
27 ; CHECK: G_STORE %0(s64)
28 ; CHECK: G_STORE [[HI]]
32 %3:_(s128) = G_LOAD %2(p0) :: (load 16)
33 %4:_(s128) = G_INSERT %3(s128), %0(s64), 0
34 G_STORE %4(s128), %2(p0) :: (store 16)
44 ; Low insertion wipes out the old register entirely, so %0 gets forwarded
45 ; to the G_STORE again. Second insertion is real.
46 ; CHECK-LABEL: name: test_inserts_2
47 ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
48 ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
49 ; CHECK: [[NEWHI:%[0-9]+]]:_(s64) = G_INSERT [[HI]], %1(s32), 0
50 ; CHECK: G_STORE %0(s64)
51 ; CHECK: G_STORE [[NEWHI]]
55 %3:_(s128) = G_LOAD %2(p0) :: (load 16)
56 %4:_(s128) = G_INSERT %3(s128), %0(s64), 0
57 %5:_(s128) = G_INSERT %4(s128), %1(s32), 64
58 G_STORE %5(s128), %2(p0) :: (store 16)
68 ; I'm not entirely convinced inserting a p0 into an s64 is valid, but it's
69 ; certainly better than the alternative of directly forwarding the value
70 ; which would cause a nasty type mismatch.
71 ; CHECK-LABEL: name: test_inserts_3
72 ; CHECK: [[LO:%[0-9]+]]:_(s64) = G_LOAD
73 ; CHECK: [[HI:%[0-9]+]]:_(s64) = G_LOAD
74 ; CHECK: [[NEWLO:%[0-9]+]]:_(s64) = G_PTRTOINT %0(p0)
75 ; CHECK: G_STORE [[NEWLO]](s64)
76 ; CHECK: G_STORE [[HI]]
80 %3:_(s128) = G_LOAD %2(p0) :: (load 16)
81 %4:_(s128) = G_INSERT %3(s128), %0(p0), 0
82 G_STORE %4(s128), %2(p0) :: (store 16)
92 ; A narrow insert gets surrounded by a G_ANYEXT/G_TRUNC pair.
93 ; CHECK-LABEL: name: test_inserts_4
94 ; CHECK: [[VALEXT:%[0-9]+]]:_(s32) = COPY %2(s32)
95 ; CHECK: [[VAL:%[0-9]+]]:_(s32) = G_INSERT [[VALEXT]], %1(s1), 0
96 ; CHECK: %5:_(s8) = G_TRUNC [[VAL]](s32)
100 %1:_(s8) = G_TRUNC %5
102 %3:_(s8) = G_INSERT %1(s8), %0(s1), 0
103 G_STORE %3(s8), %2(p0) :: (store 1)
111 liveins: $x0, $x1, $x2
114 ; CHECK-LABEL: name: test_inserts_5
115 ; CHECK: [[INS_LO:%[0-9]+]]:_(s32) = G_EXTRACT %2(s64), 0
116 ; CHECK: [[VAL_LO:%[0-9]+]]:_(s64) = G_INSERT %0, [[INS_LO]](s32), 32
117 ; CHECK: [[INS_HI:%[0-9]+]]:_(s32) = G_EXTRACT %2(s64), 32
118 ; CHECK: [[VAL_HI:%[0-9]+]]:_(s64) = G_INSERT %1, [[INS_HI]](s32), 0
119 ; CHECK: %4:_(s128) = G_MERGE_VALUES [[VAL_LO]](s64), [[VAL_HI]](s64)
123 %3:_(s128) = G_MERGE_VALUES %0, %1
124 %4:_(s128) = G_INSERT %3, %2, 32
125 %5:_(s64) = G_TRUNC %4
134 liveins: $x0, $x1, $x2
137 ; CHECK-LABEL: name: test_inserts_6
138 ; CHECK: [[VAL_LO:%[0-9]+]]:_(s64) = G_INSERT %0, %2(s32), 32
139 ; CHECK: %4:_(s128) = G_MERGE_VALUES [[VAL_LO]](s64), %1(s64)
143 %3:_(s128) = G_MERGE_VALUES %0, %1
144 %4:_(s128) = G_INSERT %3, %2, 32
145 %5:_(s64) = G_TRUNC %4
151 name: test_inserts_nonpow2
154 liveins: $x0, $x1, $x2
157 ; CHECK-LABEL: name: test_inserts_nonpow2
158 ; CHECK: [[C:%[0-9]+]]:_(s64) = COPY $x3
159 ; CHECK: $x0 = COPY [[C]]
164 %4:_(s192) = G_MERGE_VALUES %0, %1, %2
165 %5:_(s192) = G_INSERT %4, %3, 0
166 %6:_(s64), %7:_(s64), %8:_(s64) = G_UNMERGE_VALUES %5