Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / LoongArch / bstrins_w.ll
blobdfbe000841cdcbdf5481ddce19a2d6a6987dfcb6
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s
4 ;; Test generation of the bstrins.w instruction.
5 ;; There are 8 patterns that can be matched to bstrins.w. 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 i32 @pat1(i32 %a, i32 %b) nounwind {
13 ; CHECK-LABEL: pat1:
14 ; CHECK:       # %bb.0:
15 ; CHECK-NEXT:    bstrins.w $a0, $a1, 19, 8
16 ; CHECK-NEXT:    ret
17   %and1 = and i32 %a, -1048321  ; 0xfff000ff
18   %shl = shl i32 %b, 8
19   %and2 = and i32 %shl, 1048320 ; 0x000fff00
20   %or = or i32 %and1, %and2
21   ret i32 %or
24 define i32 @pat1_swap(i32 %a, i32 %b) nounwind {
25 ; CHECK-LABEL: pat1_swap:
26 ; CHECK:       # %bb.0:
27 ; CHECK-NEXT:    bstrins.w $a0, $a1, 19, 8
28 ; CHECK-NEXT:    ret
29   %and1 = and i32 %a, -1048321  ; 0xfff000ff
30   %shl = shl i32 %b, 8
31   %and2 = and i32 %shl, 1048320 ; 0x000fff00
32   %or = or i32 %and2, %and1
33   ret i32 %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 i32 @pat2(i32 %a, i32 %b) nounwind {
41 ; CHECK-LABEL: pat2:
42 ; CHECK:       # %bb.0:
43 ; CHECK-NEXT:    bstrins.w $a0, $a1, 19, 8
44 ; CHECK-NEXT:    ret
45   %and1 = and i32 %a, -1048321 ; 0xfff000ff
46   %and2 = and i32 %b, 4095     ; 0x00000fff
47   %shl = shl i32 %and2, 8
48   %or = or i32 %and1, %shl
49   ret i32 %or
52 define i32 @pat2_swap(i32 %a, i32 %b) nounwind {
53 ; CHECK-LABEL: pat2_swap:
54 ; CHECK:       # %bb.0:
55 ; CHECK-NEXT:    bstrins.w $a0, $a1, 19, 8
56 ; CHECK-NEXT:    ret
57   %and1 = and i32 %a, -1048321 ; 0xfff000ff
58   %and2 = and i32 %b, 4095     ; 0x00000fff
59   %shl = shl i32 %and2, 8
60   %or = or i32 %shl, %and1
61   ret i32 %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 i32 @pat3(i32 %a, i32 %b) nounwind {
69 ; CHECK-LABEL: pat3:
70 ; CHECK:       # %bb.0:
71 ; CHECK-NEXT:    andi $a1, $a1, 288
72 ; CHECK-NEXT:    srli.w $a1, $a1, 4
73 ; CHECK-NEXT:    bstrins.w $a0, $a1, 11, 4
74 ; CHECK-NEXT:    ret
75   %and1 = and i32 %a, -4081 ; 0xfffff00f
76   %and2 = and i32 %b, 288   ; 0x00000120
77   %or = or i32 %and1, %and2
78   ret i32 %or
81 define i32 @pat3_swap(i32 %a, i32 %b) nounwind {
82 ; CHECK-LABEL: pat3_swap:
83 ; CHECK:       # %bb.0:
84 ; CHECK-NEXT:    andi $a1, $a1, 288
85 ; CHECK-NEXT:    srli.w $a1, $a1, 4
86 ; CHECK-NEXT:    bstrins.w $a0, $a1, 11, 4
87 ; CHECK-NEXT:    ret
88   %and1 = and i32 %a, -4081 ; 0xfffff00f
89   %and2 = and i32 %b, 288   ; 0x00000120
90   %or = or i32 %and2, %and1
91   ret i32 %or
94 define i32 @pat3_positive_mask0(i32 %a, i32 %b) nounwind {
95 ; CHECK-LABEL: pat3_positive_mask0:
96 ; CHECK:       # %bb.0:
97 ; CHECK-NEXT:    srli.w $a1, $a1, 28
98 ; CHECK-NEXT:    bstrins.w $a0, $a1, 31, 28
99 ; CHECK-NEXT:    ret
100   %and1 = and i32 %a, 268435455  ; 0x0fffffff
101   %and2 = and i32 %b, 4026531840 ; 0xf0000000
102   %or = or i32 %and1, %and2
103   ret i32 %or
106 ;; Pattern 4
107 ;; R = or (and X, mask), (shl Y, shamt)
108 ;; =>
109 ;; R = BSTRINS X, Y, 31, shamt
110 define i32 @pat4(i32 %a, i32 %b) nounwind {
111 ; CHECK-LABEL: pat4:
112 ; CHECK:       # %bb.0:
113 ; CHECK-NEXT:    bstrins.w $a0, $a1, 31, 28
114 ; CHECK-NEXT:    ret
115   %and = and i32 %a, 268435455 ; 0x0fffffff
116   %shl = shl i32 %b, 28
117   %or = or i32 %and, %shl
118   ret i32 %or
121 define i32 @pat4_swap(i32 %a, i32 %b) nounwind {
122 ; CHECK-LABEL: pat4_swap:
123 ; CHECK:       # %bb.0:
124 ; CHECK-NEXT:    bstrins.w $a0, $a1, 31, 28
125 ; CHECK-NEXT:    ret
126   %and = and i32 %a, 268435455 ; 0x0fffffff
127   %shl = shl i32 %b, 28
128   %or = or i32 %shl, %and
129   ret i32 %or
132 ;; Pattern 5
133 ;; R = or (and X, mask), const
134 ;; =>
135 ;; R = BSTRINS X, (const >> lsb), msb, lsb
136 define i32 @pat5(i32 %a) nounwind {
137 ; CHECK-LABEL: pat5:
138 ; CHECK:       # %bb.0:
139 ; CHECK-NEXT:    lu12i.w $a1, 1
140 ; CHECK-NEXT:    ori $a1, $a1, 564
141 ; CHECK-NEXT:    bstrins.w $a0, $a1, 23, 8
142 ; CHECK-NEXT:    ret
143   %and = and i32 %a, 4278190335 ; 0xff0000ff
144   %or = or i32 %and, 1192960    ; 0x00123400
145   ret i32 %or
148 ;; Pattern 6: a = b | ((c & mask) << shamt)
149 ;; In this testcase b is 0x10000002, but in fact we do not require b being a
150 ;; constant. As long as all positions in b to be overwritten by the incoming
151 ;; bits are known to be zero, the pattern could be matched.
152 define i32 @pat6(i32 %c) nounwind {
153 ; CHECK-LABEL: pat6:
154 ; CHECK:       # %bb.0:
155 ; CHECK-NEXT:    lu12i.w $a1, 65536
156 ; CHECK-NEXT:    ori $a1, $a1, 2
157 ; CHECK-NEXT:    bstrins.w $a1, $a0, 27, 4
158 ; CHECK-NEXT:    move $a0, $a1
159 ; CHECK-NEXT:    ret
160   %and = and i32 %c, 16777215  ; 0x00ffffff
161   %shl = shl i32 %and, 4
162   %or = or i32 %shl, 268435458 ; 0x10000002
163   ret i32 %or
166 ;; Pattern 7: a = b | ((c << shamt) & shifted_mask)
167 ;; Similar to pattern 6.
168 define i32 @pat7(i32 %c) nounwind {
169 ; CHECK-LABEL: pat7:
170 ; CHECK:       # %bb.0:
171 ; CHECK-NEXT:    lu12i.w $a1, 65536
172 ; CHECK-NEXT:    ori $a1, $a1, 2
173 ; CHECK-NEXT:    bstrins.w $a1, $a0, 27, 4
174 ; CHECK-NEXT:    move $a0, $a1
175 ; CHECK-NEXT:    ret
176   %shl = shl i32 %c, 4
177   %and = and i32 %shl, 268435440 ; 0x0ffffff0
178   %or = or i32 %and, 268435458   ; 0x10000002
179   ret i32 %or
182 ;; Pattern 8: a = b | (c & shifted_mask)
183 ;; Similar to pattern 7 but without shift to c.
184 define i32 @pat8(i32 %c) nounwind {
185 ; CHECK-LABEL: pat8:
186 ; CHECK:       # %bb.0:
187 ; CHECK-NEXT:    srli.w $a1, $a0, 4
188 ; CHECK-NEXT:    lu12i.w $a0, 65536
189 ; CHECK-NEXT:    ori $a0, $a0, 2
190 ; CHECK-NEXT:    bstrins.w $a0, $a1, 27, 4
191 ; CHECK-NEXT:    ret
192   %and = and i32 %c, 268435440 ; 0x0ffffff0
193   %or = or i32 %and, 268435458 ; 0x10000002
194   ret i32 %or
197 ;; Test that bstrins.w is not generated because constant OR operand
198 ;; doesn't fit into bits cleared by constant AND operand.
199 define i32 @no_bstrins_w(i32 %a) nounwind {
200 ; CHECK-LABEL: no_bstrins_w:
201 ; CHECK:       # %bb.0:
202 ; CHECK-NEXT:    lu12i.w $a1, 291
203 ; CHECK-NEXT:    ori $a1, $a1, 1104
204 ; CHECK-NEXT:    or $a0, $a0, $a1
205 ; CHECK-NEXT:    lu12i.w $a1, -3805
206 ; CHECK-NEXT:    ori $a1, $a1, 1279
207 ; CHECK-NEXT:    and $a0, $a0, $a1
208 ; CHECK-NEXT:    ret
209   %and = and i32 %a, 4278190335 ; 0xff0000ff
210   %or = or i32 %and, 1193040    ; 0x00123450
211   ret i32 %or