Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / LoongArch / bstrins_d.ll
blobfe1f6270f966d3197f55b172b6fee9729f8d2b62
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
4 ;; Test generation of the bstrins.d instruction.
5 ;; There are 8 patterns that can be matched to bstrins.d. See performORCombine
6 ;; for details.
8 ;; Pattern 1
9 ;; R = or (and X, mask0), (and (shl Y, lsb), mask1)
10 ;; =>
11 ;; R = BSTRINS X, Y, msb, lsb
12 define i64 @pat1(i64 %a, i64 %b) nounwind {
13 ; CHECK-LABEL: pat1:
14 ; CHECK:       # %bb.0:
15 ; CHECK-NEXT:    bstrins.d $a0, $a1, 39, 16
16 ; CHECK-NEXT:    ret
17   %and1 = and i64 %a, -1099511562241  ; 0xffffff000000ffff
18   %shl = shl i64 %b, 16
19   %and2 = and i64 %shl, 1099511562240 ; 0x000000ffffff0000
20   %or = or i64 %and1, %and2
21   ret i64 %or
24 define i64 @pat1_swap(i64 %a, i64 %b) nounwind {
25 ; CHECK-LABEL: pat1_swap:
26 ; CHECK:       # %bb.0:
27 ; CHECK-NEXT:    bstrins.d $a0, $a1, 39, 16
28 ; CHECK-NEXT:    ret
29   %and1 = and i64 %a, -1099511562241  ; 0xffffff000000ffff
30   %shl = shl i64 %b, 16
31   %and2 = and i64 %shl, 1099511562240 ; 0x000000ffffff0000
32   %or = or i64 %and2, %and1
33   ret i64 %or
36 ;; Pattern 2
37 ;; R = or (and X, mask0), (shl (and Y, mask1), lsb)
38 ;; =>
39 ;; R = BSTRINS X, Y, msb, lsb
40 define i64 @pat2(i64 %a, i64 %b) nounwind {
41 ; CHECK-LABEL: pat2:
42 ; CHECK:       # %bb.0:
43 ; CHECK-NEXT:    bstrins.d $a0, $a1, 39, 16
44 ; CHECK-NEXT:    ret
45   %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff
46   %and2 = and i64 %b, 16777215       ; 0x0000000000ffffff
47   %shl = shl i64 %and2, 16
48   %or = or i64 %and1, %shl
49   ret i64 %or
52 define i64 @pat2_swap(i64 %a, i64 %b) nounwind {
53 ; CHECK-LABEL: pat2_swap:
54 ; CHECK:       # %bb.0:
55 ; CHECK-NEXT:    bstrins.d $a0, $a1, 39, 16
56 ; CHECK-NEXT:    ret
57   %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff
58   %and2 = and i64 %b, 16777215       ; 0x0000000000ffffff
59   %shl = shl i64 %and2, 16
60   %or = or i64 %shl, %and1
61   ret i64 %or
64 ;; Pattern 3
65 ;; R = or (and X, mask0), (and Y, mask1)
66 ;; =>
67 ;; R = BSTRINS X, (srl (and Y, mask1), lsb), msb, lsb
68 define i64 @pat3(i64 %a, i64 %b) nounwind {
69 ; CHECK-LABEL: pat3:
70 ; CHECK:       # %bb.0:
71 ; CHECK-NEXT:    andi $a1, $a1, 288
72 ; CHECK-NEXT:    srli.d $a1, $a1, 4
73 ; CHECK-NEXT:    bstrins.d $a0, $a1, 11, 4
74 ; CHECK-NEXT:    ret
75   %and1 = and i64 %a, -4081 ; 0xfffffffffffff00f
76   %and2 = and i64 %b, 288   ; 0x0000000000000120
77   %or = or i64 %and1, %and2
78   ret i64 %or
81 define i64 @pat3_swap(i64 %a, i64 %b) nounwind {
82 ; CHECK-LABEL: pat3_swap:
83 ; CHECK:       # %bb.0:
84 ; CHECK-NEXT:    andi $a1, $a1, 288
85 ; CHECK-NEXT:    srli.d $a1, $a1, 4
86 ; CHECK-NEXT:    bstrins.d $a0, $a1, 11, 4
87 ; CHECK-NEXT:    ret
88   %and1 = and i64 %a, -4081 ; 0xfffffffffffff00f
89   %and2 = and i64 %b, 288   ; 0x0000000000000120
90   %or = or i64 %and2, %and1
91   ret i64 %or
94 ;; Pattern 4
95 ;; R = or (and X, mask), (shl Y, shamt)
96 ;; =>
97 ;; R = BSTRINS X, Y, 63, shamt
98 define i64 @pat4(i64 %a, i64 %b) nounwind {
99 ; CHECK-LABEL: pat4:
100 ; CHECK:       # %bb.0:
101 ; CHECK-NEXT:    bstrins.d $a0, $a1, 63, 8
102 ; CHECK-NEXT:    ret
103   %and = and i64 %a, 255
104   %shl = shl i64 %b, 8
105   %or = or i64 %and, %shl
106   ret i64 %or
109 define i64 @pat4_swap(i64 %a, i64 %b) nounwind {
110 ; CHECK-LABEL: pat4_swap:
111 ; CHECK:       # %bb.0:
112 ; CHECK-NEXT:    bstrins.d $a0, $a1, 63, 8
113 ; CHECK-NEXT:    ret
114   %and = and i64 %a, 255
115   %shl = shl i64 %b, 8
116   %or = or i64 %shl, %and
117   ret i64 %or
120 ;; Pattern 5
121 ;; R = or (and X, mask0), const
122 ;; =>
123 ;; R = BSTRINS X, (const >> lsb), msb, lsb
124 define i64 @pat5(i64 %a) nounwind {
125 ; CHECK-LABEL: pat5:
126 ; CHECK:       # %bb.0:
127 ; CHECK-NEXT:    lu12i.w $a1, 74565
128 ; CHECK-NEXT:    ori $a1, $a1, 1656
129 ; CHECK-NEXT:    bstrins.d $a0, $a1, 47, 16
130 ; CHECK-NEXT:    ret
131   %and = and i64 %a, 18446462598732906495 ; 0xffff00000000ffff
132   %or = or i64 %and, 20015998304256       ; 0x0000123456780000
133   ret i64 %or
136 ;; Pattern 6: a = b | ((c & mask) << shamt)
137 ;; In this testcase b is 0x123456000000789a, but in fact we do not require b
138 ;; being a constant. As long as all positions in b to be overwritten by the
139 ;; incoming bits are known to be zero, the pattern could be matched.
140 define i64 @pat6(i64 %c) nounwind {
141 ; CHECK-LABEL: pat6:
142 ; CHECK:       # %bb.0:
143 ; CHECK-NEXT:    lu12i.w $a1, 7
144 ; CHECK-NEXT:    ori $a1, $a1, 2202
145 ; CHECK-NEXT:    lu32i.d $a1, 284160
146 ; CHECK-NEXT:    lu52i.d $a1, $a1, 291
147 ; CHECK-NEXT:    bstrins.d $a1, $a0, 39, 16
148 ; CHECK-NEXT:    move $a0, $a1
149 ; CHECK-NEXT:    ret
150   %and = and i64 %c, 16777215            ; 0x0000000000ffffff
151   %shl = shl i64 %and, 16
152   %or = or i64 %shl, 1311767949471676570 ; 0x123456000000789a
153   ret i64 %or
156 ;; Pattern 7: a = b | ((c << shamt) & shifted_mask)
157 ;; Similar to pattern 6.
158 define i64 @pat7(i64 %c) nounwind {
159 ; CHECK-LABEL: pat7:
160 ; CHECK:       # %bb.0:
161 ; CHECK-NEXT:    lu12i.w $a1, 7
162 ; CHECK-NEXT:    ori $a1, $a1, 2202
163 ; CHECK-NEXT:    lu32i.d $a1, 284160
164 ; CHECK-NEXT:    lu52i.d $a1, $a1, 291
165 ; CHECK-NEXT:    bstrins.d $a1, $a0, 39, 16
166 ; CHECK-NEXT:    move $a0, $a1
167 ; CHECK-NEXT:    ret
168   %shl = shl i64 %c, 16
169   %and = and i64 %shl, 1099511562240     ; 0x000000ffffff0000
170   %or = or i64 %and, 1311767949471676570 ; 0x123456000000789a
171   ret i64 %or
174 ;; Pattern 8: a = b | (c & shifted_mask)
175 ;; Similar to pattern 7 but without shift to c.
176 define i64 @pat8(i64 %c) nounwind {
177 ; CHECK-LABEL: pat8:
178 ; CHECK:       # %bb.0:
179 ; CHECK-NEXT:    srli.d $a1, $a0, 16
180 ; CHECK-NEXT:    lu12i.w $a0, 7
181 ; CHECK-NEXT:    ori $a0, $a0, 2202
182 ; CHECK-NEXT:    lu32i.d $a0, 284160
183 ; CHECK-NEXT:    lu52i.d $a0, $a0, 291
184 ; CHECK-NEXT:    bstrins.d $a0, $a1, 39, 16
185 ; CHECK-NEXT:    ret
186   %and = and i64 %c, 1099511562240       ; 0x000000ffffff0000
187   %or = or i64 %and, 1311767949471676570 ; 0x123456000000789a
188   ret i64 %or
191 ;; Test that bstrins.d is not generated because constant OR operand
192 ;; doesn't fit into bits cleared by constant AND operand.
193 define i64 @no_bstrins_d(i64 %a) nounwind {
194 ; CHECK-LABEL: no_bstrins_d:
195 ; CHECK:       # %bb.0:
196 ; CHECK-NEXT:    lu12i.w $a1, 354185
197 ; CHECK-NEXT:    lu32i.d $a1, 4660
198 ; CHECK-NEXT:    or $a0, $a0, $a1
199 ; CHECK-NEXT:    lu12i.w $a1, 354191
200 ; CHECK-NEXT:    ori $a1, $a1, 4095
201 ; CHECK-NEXT:    lu32i.d $a1, -60876
202 ; CHECK-NEXT:    and $a0, $a0, $a1
203 ; CHECK-NEXT:    ret
204   %and = and i64 %a, 18446462598732906495 ; 0xffff00000000ffff
205   %or = or i64 %and, 20015998341120       ; 0x0000123456789000
206   ret i64 %or