1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
4 # Test widening and narrowing on test bit operations using subregister copies
7 @glob = external dso_local unnamed_addr global i1, align 4
8 define void @s1_no_copy() { ret void }
9 define void @s16_no_copy() { ret void }
10 define void @p0_no_copy() { ret void }
11 define void @widen_s32_to_s64() { ret void }
12 define void @widen_s16_to_s64() { ret void }
13 define void @narrow_s64_to_s32() { ret void }
21 tracksRegLiveness: true
23 ; CHECK-LABEL: name: s1_no_copy
25 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
26 ; CHECK: %narrow:gpr32 = IMPLICIT_DEF
27 ; CHECK: TBNZW %narrow, 0, %bb.1
32 successors: %bb.0, %bb.1
33 %narrow:gpr(s1) = G_IMPLICIT_DEF
35 ; There should be no copy here, because the s1 can be selected to a GPR32.
36 G_BRCOND %narrow(s1), %bb.1
46 tracksRegLiveness: true
48 ; CHECK-LABEL: name: s16_no_copy
50 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
51 ; CHECK: %narrow:gpr32 = IMPLICIT_DEF
52 ; CHECK: TBNZW %narrow, 0, %bb.1
57 successors: %bb.0, %bb.1
58 %narrow:gpr(s16) = G_IMPLICIT_DEF
59 %trunc:gpr(s1) = G_TRUNC %narrow(s16)
61 ; Look through the G_TRUNC to get the G_IMPLICIT_DEF. We don't need a
62 ; SUBREG_TO_REG here, because the s16 will end up on a 32-bit register.
63 G_BRCOND %trunc(s1), %bb.1
73 tracksRegLiveness: true
75 ; CHECK-LABEL: name: p0_no_copy
77 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
78 ; CHECK: %glob:gpr64common = MOVaddr target-flags(aarch64-page) @glob, target-flags(aarch64-pageoff, aarch64-nc) @glob
79 ; CHECK: %load:gpr32 = LDRBBui %glob, 0 :: (dereferenceable load (s8) from @glob, align 4)
80 ; CHECK: TBNZW %load, 0, %bb.1
85 successors: %bb.0, %bb.1
86 %glob:gpr(p0) = G_GLOBAL_VALUE @glob
87 %load:gpr(s8) = G_LOAD %glob(p0) :: (dereferenceable load (s8) from @glob, align 4)
88 %trunc:gpr(s1) = G_TRUNC %load(s8)
90 ; Look through G_TRUNC to get the load. The load is into a s8, which will
91 ; be selected to a GPR32, so we don't need a copy.
92 G_BRCOND %trunc(s1), %bb.1
98 name: widen_s32_to_s64
101 regBankSelected: true
102 tracksRegLiveness: true
104 ; CHECK-LABEL: name: widen_s32_to_s64
106 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
107 ; CHECK: liveins: $w0
108 ; CHECK: %reg:gpr32all = COPY $w0
109 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, %reg, %subreg.sub_32
110 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
111 ; CHECK: TBZX [[COPY]], 33, %bb.1
114 ; CHECK: RET_ReallyLR
116 successors: %bb.0, %bb.1
118 %reg:gpr(s32) = COPY $w0
119 %zext:gpr(s64) = G_ZEXT %reg(s32)
120 %bit:gpr(s64) = G_CONSTANT i64 8589934592
121 %zero:gpr(s64) = G_CONSTANT i64 0
122 %and:gpr(s64) = G_AND %zext, %bit
123 %cmp:gpr(s32) = G_ICMP intpred(eq), %and(s64), %zero
125 ; We should widen using a SUBREG_TO_REG here, because we need a TBZX to get
126 ; bit 33. The subregister should be sub_32.
127 %trunc:gpr(s1) = G_TRUNC %cmp(s32)
128 G_BRCOND %trunc(s1), %bb.1
134 name: widen_s16_to_s64
137 regBankSelected: true
138 tracksRegLiveness: true
140 ; CHECK-LABEL: name: widen_s16_to_s64
142 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
143 ; CHECK: %reg:gpr32 = IMPLICIT_DEF
144 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, %reg, %subreg.sub_32
145 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
146 ; CHECK: TBZX [[COPY]], 33, %bb.1
149 ; CHECK: RET_ReallyLR
151 successors: %bb.0, %bb.1
152 %reg:gpr(s16) = G_IMPLICIT_DEF
153 %zext:gpr(s64) = G_ZEXT %reg(s16)
154 %bit:gpr(s64) = G_CONSTANT i64 8589934592
155 %zero:gpr(s64) = G_CONSTANT i64 0
156 %and:gpr(s64) = G_AND %zext, %bit
157 %cmp:gpr(s32) = G_ICMP intpred(eq), %and(s64), %zero
159 ; We should widen using a SUBREG_TO_REG here, because we need a TBZX to get
160 ; bit 33. The subregister should be sub_32, because s16 will end up on a
162 %trunc:gpr(s1) = G_TRUNC %cmp(s32)
163 G_BRCOND %trunc(s1), %bb.1
169 name: narrow_s64_to_s32
172 regBankSelected: true
173 tracksRegLiveness: true
175 ; CHECK-LABEL: name: narrow_s64_to_s32
177 ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
178 ; CHECK: liveins: $x0
179 ; CHECK: %wide:gpr64all = COPY $x0
180 ; CHECK: [[COPY:%[0-9]+]]:gpr32all = COPY %wide.sub_32
181 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
182 ; CHECK: TBNZW [[COPY1]], 0, %bb.1
185 ; CHECK: RET_ReallyLR
187 successors: %bb.0, %bb.1
189 %wide:gpr(s64) = COPY $x0
191 ; We should narrow using a subregister copy here.
192 %trunc:gpr(s1) = G_TRUNC %wide(s64)
193 G_BRCOND %trunc(s1), %bb.1